vmpooler 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 033cdee6f8934932e9e717b8b229b36541fe2f88
4
- data.tar.gz: d798c6417320e4942bf0965ed3c1e2d303e0bab6
3
+ metadata.gz: a1b32e5280b92e461243bc99e275e1637fe3c644
4
+ data.tar.gz: 702ee61515185102a99cecc1d1475b84f2c19ada
5
5
  SHA512:
6
- metadata.gz: a45de99b68aaf08784fbfac2793a9da60d38c9a8af20ae802362015841e6962dfb2ab027dbfcc7792d8808130752991c3419e95a4ea0764dc625c8a1b97dd5d0
7
- data.tar.gz: 68dbfedba323a249e0a0bace756f2aec21ce1e9a770482b477ea9b197f9ff7a86ba55cdc29a9493756f713c514689f1db66a5196ea01f8f42126315e726f1daa
6
+ metadata.gz: 9566067bbaee8024bdcd05d715082e158a61503de81e9d35a7600ba9567e4f033638350718143c86c17db0e912a1fb42f42032b465350afba666a7f3856c8acb
7
+ data.tar.gz: 415ebd0a8bbbd125ec0a0972be930197f88ac1d927f41683e526aec4465406fe0a6954750892b0b1991b16046686ad64420bb103821620e68e8a017a9b37f208
@@ -1,15 +1,16 @@
1
1
  module Vmpooler
2
2
  require 'date'
3
3
  require 'json'
4
- require 'open-uri'
5
4
  require 'net/ldap'
5
+ require 'open-uri'
6
+ require 'pickup'
6
7
  require 'rbvmomi'
7
8
  require 'redis'
9
+ require 'set'
8
10
  require 'sinatra/base'
9
11
  require 'time'
10
12
  require 'timeout'
11
13
  require 'yaml'
12
- require 'set'
13
14
 
14
15
  %w[api graphite logger pool_manager statsd dummy_statsd generic_connection_pool].each do |lib|
15
16
  require "vmpooler/#{lib}"
@@ -37,15 +37,38 @@ module Vmpooler
37
37
  end
38
38
 
39
39
  def fetch_single_vm(template)
40
- vm = backend.spop('vmpooler__ready__' + template)
41
- return [vm, template] if vm
42
-
40
+ template_backends = [template]
43
41
  aliases = Vmpooler::API.settings.config[:alias]
44
- if aliases && aliased_template = aliases[template]
45
- vm = backend.spop('vmpooler__ready__' + aliased_template)
46
- return [vm, aliased_template] if vm
42
+ if aliases
43
+ template_backends << aliases[template] if aliases[template]
44
+
45
+ pool_index = pool_index(pools)
46
+ weighted_pools = {}
47
+ template_backends.each do |t|
48
+ next unless pool_index.key? t
49
+ index = pool_index[t]
50
+ clone_target = pools[index]['clone_target'] || config['clone_target']
51
+ next unless config.key?('backend_weight')
52
+ weight = config['backend_weight'][clone_target]
53
+ if weight
54
+ weighted_pools[t] = weight
55
+ end
56
+ end
57
+
58
+ if weighted_pools.count == template_backends.count
59
+ pickup = Pickup.new(weighted_pools)
60
+ selection = pickup.pick
61
+ template_backends.delete(selection)
62
+ template_backends.unshift(selection)
63
+ else
64
+ template_backends = template_backends.sample(template_backends.count)
65
+ end
47
66
  end
48
67
 
68
+ template_backends.each do |t|
69
+ vm = backend.spop('vmpooler__ready__' + t)
70
+ return [vm, t] if vm
71
+ end
49
72
  [nil, nil]
50
73
  end
51
74
 
@@ -188,8 +188,10 @@ module Vmpooler
188
188
 
189
189
  # Check if the hostname has magically changed from underneath Pooler
190
190
  vm_hash = provider.get_vm(pool['name'], vm)
191
+ return unless vm_hash.is_a? Hash
191
192
  hostname = vm_hash['hostname']
192
193
 
194
+ return if hostname.nil?
193
195
  return if hostname.empty?
194
196
  return if hostname == vm
195
197
  $redis.smove('vmpooler__ready__' + pool['name'], 'vmpooler__completed__' + pool['name'], vm)
@@ -243,20 +245,18 @@ module Vmpooler
243
245
  end
244
246
 
245
247
  # Clone a VM
246
- def clone_vm(pool, provider)
248
+ def clone_vm(pool_name, provider)
247
249
  Thread.new do
248
250
  begin
249
- _clone_vm(pool, provider)
251
+ _clone_vm(pool_name, provider)
250
252
  rescue => err
251
- $logger.log('s', "[!] [#{pool['name']}] failed while cloning VM with an error: #{err}")
253
+ $logger.log('s', "[!] [#{pool_name}] failed while cloning VM with an error: #{err}")
252
254
  raise
253
255
  end
254
256
  end
255
257
  end
256
258
 
257
- def _clone_vm(pool, provider)
258
- pool_name = pool['name']
259
-
259
+ def _clone_vm(pool_name, provider)
260
260
  # Generate a randomized hostname
261
261
  o = [('a'..'z'), ('0'..'9')].map(&:to_a).flatten
262
262
  new_vmname = $config[:config]['prefix'] + o[rand(25)] + (0...14).map { o[rand(o.length)] }.join
@@ -723,7 +723,16 @@ module Vmpooler
723
723
  end
724
724
 
725
725
  def prepare_template(pool, provider)
726
- provider.create_template_delta_disks(pool) if $config[:config]['create_template_delta_disks']
726
+ if $config[:config]['create_template_delta_disks']
727
+ unless $redis.sismember('vmpooler__template__deltas', pool['template'])
728
+ begin
729
+ provider.create_template_delta_disks(pool)
730
+ $redis.sadd('vmpooler__template__deltas', pool['template'])
731
+ rescue => err
732
+ $logger.log('s', "[!] [#{pool['name']}] failed while preparing a template with an error. As a result vmpooler could not create the template delta disks. Either a template delta disk already exists, or the template delta disk creation failed. The error is: #{err}")
733
+ end
734
+ end
735
+ end
727
736
  $redis.hset('vmpooler__template__prepared', pool['name'], pool['template'])
728
737
  end
729
738
 
@@ -779,7 +788,9 @@ module Vmpooler
779
788
  $logger.log('s', "[*] [#{pool['name']}] is ready for use")
780
789
  end
781
790
 
782
- def remove_excess_vms(pool, provider, ready, total)
791
+ def remove_excess_vms(pool)
792
+ ready = $redis.scard("vmpooler__ready__#{pool['name']}")
793
+ total = $redis.scard("vmpooler__pending__#{pool['name']}") + ready
783
794
  return if total.nil?
784
795
  return if total == 0
785
796
  mutex = pool_mutex(pool['name'])
@@ -811,17 +822,7 @@ module Vmpooler
811
822
  end
812
823
  end
813
824
 
814
- def _check_pool(pool, provider)
815
- pool_check_response = {
816
- discovered_vms: 0,
817
- checked_running_vms: 0,
818
- checked_ready_vms: 0,
819
- checked_pending_vms: 0,
820
- destroyed_vms: 0,
821
- migrated_vms: 0,
822
- cloned_vms: 0
823
- }
824
- # INVENTORY
825
+ def create_inventory(pool, provider, pool_check_response)
825
826
  inventory = {}
826
827
  begin
827
828
  mutex = pool_mutex(pool['name'])
@@ -844,103 +845,170 @@ module Vmpooler
844
845
  end
845
846
  end
846
847
  rescue => err
847
- $logger.log('s', "[!] [#{pool['name']}] _check_pool failed with an error while inspecting inventory: #{err}")
848
- return pool_check_response
848
+ $logger.log('s', "[!] [#{pool['name']}] _check_pool failed with an error while running create_inventory: #{err}")
849
+ raise(err)
849
850
  end
851
+ inventory
852
+ end
850
853
 
851
- # RUNNING
852
- $redis.smembers("vmpooler__running__#{pool['name']}").each do |vm|
854
+ def check_running_pool_vms(pool_name, provider, pool_check_response, inventory)
855
+ $redis.smembers("vmpooler__running__#{pool_name}").each do |vm|
853
856
  if inventory[vm]
854
857
  begin
855
858
  vm_lifetime = $redis.hget('vmpooler__vm__' + vm, 'lifetime') || $config[:config]['vm_lifetime'] || 12
856
859
  pool_check_response[:checked_running_vms] += 1
857
- check_running_vm(vm, pool['name'], vm_lifetime, provider)
860
+ check_running_vm(vm, pool_name, vm_lifetime, provider)
858
861
  rescue => err
859
- $logger.log('d', "[!] [#{pool['name']}] _check_pool with an error while evaluating running VMs: #{err}")
862
+ $logger.log('d', "[!] [#{pool_name}] _check_pool with an error while evaluating running VMs: #{err}")
860
863
  end
861
864
  else
862
- move_vm_queue(pool['name'], vm, 'running', 'completed', 'is a running VM but is missing from inventory. Marking as completed.')
865
+ move_vm_queue(pool_name, vm, 'running', 'completed', 'is a running VM but is missing from inventory. Marking as completed.')
863
866
  end
864
867
  end
868
+ end
865
869
 
866
- # READY
867
- $redis.smembers("vmpooler__ready__#{pool['name']}").each do |vm|
870
+ def check_ready_pool_vms(pool_name, provider, pool_check_response, inventory, pool_ttl = 0)
871
+ $redis.smembers("vmpooler__ready__#{pool_name}").each do |vm|
868
872
  if inventory[vm]
869
873
  begin
870
874
  pool_check_response[:checked_ready_vms] += 1
871
- check_ready_vm(vm, pool, pool['ready_ttl'] || 0, provider)
875
+ check_ready_vm(vm, pool_name, pool_ttl || 0, provider)
872
876
  rescue => err
873
- $logger.log('d', "[!] [#{pool['name']}] _check_pool failed with an error while evaluating ready VMs: #{err}")
877
+ $logger.log('d', "[!] [#{pool_name}] _check_pool failed with an error while evaluating ready VMs: #{err}")
874
878
  end
875
879
  else
876
- move_vm_queue(pool['name'], vm, 'ready', 'completed', 'is a ready VM but is missing from inventory. Marking as completed.')
880
+ move_vm_queue(pool_name, vm, 'ready', 'completed', 'is a ready VM but is missing from inventory. Marking as completed.')
877
881
  end
878
882
  end
883
+ end
879
884
 
880
- # PENDING
881
- $redis.smembers("vmpooler__pending__#{pool['name']}").each do |vm|
882
- pool_timeout = pool['timeout'] || $config[:config]['timeout'] || 15
885
+ def check_pending_pool_vms(pool_name, provider, pool_check_response, inventory, pool_timeout = nil)
886
+ pool_timeout ||= $config[:config]['timeout'] || 15
887
+ $redis.smembers("vmpooler__pending__#{pool_name}").each do |vm|
883
888
  if inventory[vm]
884
889
  begin
885
890
  pool_check_response[:checked_pending_vms] += 1
886
- check_pending_vm(vm, pool['name'], pool_timeout, provider)
891
+ check_pending_vm(vm, pool_name, pool_timeout, provider)
887
892
  rescue => err
888
- $logger.log('d', "[!] [#{pool['name']}] _check_pool failed with an error while evaluating pending VMs: #{err}")
893
+ $logger.log('d', "[!] [#{pool_name}] _check_pool failed with an error while evaluating pending VMs: #{err}")
889
894
  end
890
895
  else
891
- fail_pending_vm(vm, pool['name'], pool_timeout, false)
896
+ fail_pending_vm(vm, pool_name, pool_timeout, false)
892
897
  end
893
898
  end
899
+ end
894
900
 
895
- # COMPLETED
896
- $redis.smembers("vmpooler__completed__#{pool['name']}").each do |vm|
901
+ def check_completed_pool_vms(pool_name, provider, pool_check_response, inventory)
902
+ $redis.smembers("vmpooler__completed__#{pool_name}").each do |vm|
897
903
  if inventory[vm]
898
904
  begin
899
905
  pool_check_response[:destroyed_vms] += 1
900
- destroy_vm(vm, pool['name'], provider)
906
+ destroy_vm(vm, pool_name, provider)
901
907
  rescue => err
902
- $redis.srem("vmpooler__completed__#{pool['name']}", vm)
903
- $redis.hdel("vmpooler__active__#{pool['name']}", vm)
908
+ $redis.srem("vmpooler__completed__#{pool_name}", vm)
909
+ $redis.hdel("vmpooler__active__#{pool_name}", vm)
904
910
  $redis.del("vmpooler__vm__#{vm}")
905
- $logger.log('d', "[!] [#{pool['name']}] _check_pool failed with an error while evaluating completed VMs: #{err}")
911
+ $logger.log('d', "[!] [#{pool_name}] _check_pool failed with an error while evaluating completed VMs: #{err}")
906
912
  end
907
913
  else
908
- $logger.log('s', "[!] [#{pool['name']}] '#{vm}' not found in inventory, removed from 'completed' queue")
909
- $redis.srem("vmpooler__completed__#{pool['name']}", vm)
910
- $redis.hdel("vmpooler__active__#{pool['name']}", vm)
914
+ $logger.log('s', "[!] [#{pool_name}] '#{vm}' not found in inventory, removed from 'completed' queue")
915
+ $redis.srem("vmpooler__completed__#{pool_name}", vm)
916
+ $redis.hdel("vmpooler__active__#{pool_name}", vm)
911
917
  $redis.del("vmpooler__vm__#{vm}")
912
918
  end
913
919
  end
920
+ end
914
921
 
915
- # DISCOVERED
922
+ def check_discovered_pool_vms(pool_name)
916
923
  begin
917
- $redis.smembers("vmpooler__discovered__#{pool['name']}").each do |vm|
924
+ $redis.smembers("vmpooler__discovered__#{pool_name}").each do |vm|
918
925
  %w[pending ready running completed].each do |queue|
919
- if $redis.sismember("vmpooler__#{queue}__#{pool['name']}", vm)
920
- $logger.log('d', "[!] [#{pool['name']}] '#{vm}' found in '#{queue}', removed from 'discovered' queue")
921
- $redis.srem("vmpooler__discovered__#{pool['name']}", vm)
926
+ if $redis.sismember("vmpooler__#{queue}__#{pool_name}", vm)
927
+ $logger.log('d', "[!] [#{pool_name}] '#{vm}' found in '#{queue}', removed from 'discovered' queue")
928
+ $redis.srem("vmpooler__discovered__#{pool_name}", vm)
922
929
  end
923
930
  end
924
931
 
925
- if $redis.sismember("vmpooler__discovered__#{pool['name']}", vm)
926
- $redis.smove("vmpooler__discovered__#{pool['name']}", "vmpooler__completed__#{pool['name']}", vm)
932
+ if $redis.sismember("vmpooler__discovered__#{pool_name}", vm)
933
+ $redis.smove("vmpooler__discovered__#{pool_name}", "vmpooler__completed__#{pool_name}", vm)
927
934
  end
928
935
  end
929
936
  rescue => err
930
- $logger.log('d', "[!] [#{pool['name']}] _check_pool failed with an error while evaluating discovered VMs: #{err}")
937
+ $logger.log('d', "[!] [#{pool_name}] _check_pool failed with an error while evaluating discovered VMs: #{err}")
931
938
  end
939
+ end
932
940
 
933
- # MIGRATIONS
934
- $redis.smembers("vmpooler__migrating__#{pool['name']}").each do |vm|
941
+ def check_migrating_pool_vms(pool_name, provider, pool_check_response, inventory)
942
+ $redis.smembers("vmpooler__migrating__#{pool_name}").each do |vm|
935
943
  if inventory[vm]
936
944
  begin
937
945
  pool_check_response[:migrated_vms] += 1
938
- migrate_vm(vm, pool['name'], provider)
946
+ migrate_vm(vm, pool_name, provider)
947
+ rescue => err
948
+ $logger.log('s', "[x] [#{pool_name}] '#{vm}' failed to migrate: #{err}")
949
+ end
950
+ end
951
+ end
952
+ end
953
+
954
+ def repopulate_pool_vms(pool_name, provider, pool_check_response, pool_size)
955
+ return if pool_mutex(pool_name).locked?
956
+ ready = $redis.scard("vmpooler__ready__#{pool_name}")
957
+ total = $redis.scard("vmpooler__pending__#{pool_name}") + ready
958
+
959
+ $metrics.gauge("ready.#{pool_name}", $redis.scard("vmpooler__ready__#{pool_name}"))
960
+ $metrics.gauge("running.#{pool_name}", $redis.scard("vmpooler__running__#{pool_name}"))
961
+
962
+ if $redis.get("vmpooler__empty__#{pool_name}")
963
+ $redis.del("vmpooler__empty__#{pool_name}") unless ready.zero?
964
+ elsif ready.zero?
965
+ $redis.set("vmpooler__empty__#{pool_name}", 'true')
966
+ $logger.log('s', "[!] [#{pool_name}] is empty")
967
+ end
968
+
969
+ (pool_size - total).times do
970
+ if $redis.get('vmpooler__tasks__clone').to_i < $config[:config]['task_limit'].to_i
971
+ begin
972
+ $redis.incr('vmpooler__tasks__clone')
973
+ pool_check_response[:cloned_vms] += 1
974
+ clone_vm(pool_name, provider)
939
975
  rescue => err
940
- $logger.log('s', "[x] [#{pool['name']}] '#{vm}' failed to migrate: #{err}")
976
+ $logger.log('s', "[!] [#{pool_name}] clone failed during check_pool with an error: #{err}")
977
+ $redis.decr('vmpooler__tasks__clone')
978
+ raise
941
979
  end
942
980
  end
943
981
  end
982
+ end
983
+
984
+ def _check_pool(pool, provider)
985
+ pool_check_response = {
986
+ discovered_vms: 0,
987
+ checked_running_vms: 0,
988
+ checked_ready_vms: 0,
989
+ checked_pending_vms: 0,
990
+ destroyed_vms: 0,
991
+ migrated_vms: 0,
992
+ cloned_vms: 0
993
+ }
994
+
995
+ begin
996
+ inventory = create_inventory(pool, provider, pool_check_response)
997
+ rescue => err
998
+ return(pool_check_response)
999
+ end
1000
+
1001
+ check_running_pool_vms(pool['name'], provider, pool_check_response, inventory)
1002
+
1003
+ check_ready_pool_vms(pool['name'], provider, pool_check_response, inventory, pool['ready_ttl'])
1004
+
1005
+ check_pending_pool_vms(pool['name'], provider, pool_check_response, inventory, pool['timeout'])
1006
+
1007
+ check_completed_pool_vms(pool['name'], provider, pool_check_response, inventory)
1008
+
1009
+ check_discovered_pool_vms(pool['name'])
1010
+
1011
+ check_migrating_pool_vms(pool['name'], provider, pool_check_response, inventory)
944
1012
 
945
1013
  # UPDATE TEMPLATE
946
1014
  # Evaluates a pool template to ensure templates are prepared adequately for the configured provider
@@ -948,46 +1016,15 @@ module Vmpooler
948
1016
  # Additionally, a pool will drain ready and pending instances
949
1017
  evaluate_template(pool, provider)
950
1018
 
951
- # REPOPULATE
952
- # Do not attempt to repopulate a pool while a template is updating
953
- unless pool_mutex(pool['name']).locked?
954
- ready = $redis.scard("vmpooler__ready__#{pool['name']}")
955
- total = $redis.scard("vmpooler__pending__#{pool['name']}") + ready
1019
+ # Check to see if a pool size change has been made via the configuration API
1020
+ # Since check_pool runs in a loop it does not
1021
+ # otherwise identify this change when running
1022
+ update_pool_size(pool)
956
1023
 
957
- $metrics.gauge("ready.#{pool['name']}", $redis.scard("vmpooler__ready__#{pool['name']}"))
958
- $metrics.gauge("running.#{pool['name']}", $redis.scard("vmpooler__running__#{pool['name']}"))
959
-
960
- if $redis.get("vmpooler__empty__#{pool['name']}")
961
- $redis.del("vmpooler__empty__#{pool['name']}") unless ready.zero?
962
- elsif ready.zero?
963
- $redis.set("vmpooler__empty__#{pool['name']}", 'true')
964
- $logger.log('s', "[!] [#{pool['name']}] is empty")
965
- end
966
-
967
- # Check to see if a pool size change has been made via the configuration API
968
- # Since check_pool runs in a loop it does not
969
- # otherwise identify this change when running
970
- update_pool_size(pool)
971
-
972
- if total < pool['size']
973
- (1..(pool['size'] - total)).each do |_i|
974
- if $redis.get('vmpooler__tasks__clone').to_i < $config[:config]['task_limit'].to_i
975
- begin
976
- $redis.incr('vmpooler__tasks__clone')
977
- pool_check_response[:cloned_vms] += 1
978
- clone_vm(pool, provider)
979
- rescue => err
980
- $logger.log('s', "[!] [#{pool['name']}] clone failed during check_pool with an error: #{err}")
981
- $redis.decr('vmpooler__tasks__clone')
982
- raise
983
- end
984
- end
985
- end
986
- end
987
- end
1024
+ repopulate_pool_vms(pool['name'], provider, pool_check_response, pool['size'])
988
1025
 
989
1026
  # Remove VMs in excess of the configured pool size
990
- remove_excess_vms(pool, provider, ready, total)
1027
+ remove_excess_vms(pool)
991
1028
 
992
1029
  pool_check_response
993
1030
  end
@@ -428,7 +428,7 @@ module Vmpooler
428
428
 
429
429
  def vm_ready?(_pool_name, vm_name)
430
430
  begin
431
- open_socket(vm_name)
431
+ open_socket(vm_name, global_config[:config]['domain'])
432
432
  rescue => _err
433
433
  return false
434
434
  end
@@ -1,3 +1,3 @@
1
1
  module Vmpooler
2
- VERSION = '0.2.0'.freeze
2
+ VERSION = '0.2.1'.freeze
3
3
  end
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vmpooler
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Puppet
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-07-24 00:00:00.000000000 Z
11
+ date: 2018-09-19 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: pickup
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 0.0.11
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 0.0.11
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: puma
15
29
  requirement: !ruby/object:Gem::Requirement