vmpooler 0.11.2 → 0.13.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/vmpooler +3 -1
- data/lib/vmpooler.rb +23 -1
- data/lib/vmpooler/api/helpers.rb +16 -16
- data/lib/vmpooler/api/v1.rb +294 -19
- data/lib/vmpooler/generic_connection_pool.rb +5 -23
- data/lib/vmpooler/graphite.rb +2 -0
- data/lib/vmpooler/pool_manager.rb +753 -389
- data/lib/vmpooler/providers/base.rb +2 -1
- data/lib/vmpooler/providers/dummy.rb +2 -2
- data/lib/vmpooler/providers/vsphere.rb +50 -30
- data/lib/vmpooler/version.rb +1 -1
- metadata +16 -2
@@ -14,10 +14,11 @@ module Vmpooler
|
|
14
14
|
# Provider options passed in during initialization
|
15
15
|
attr_reader :provider_options
|
16
16
|
|
17
|
-
def initialize(config, logger, metrics, name, options)
|
17
|
+
def initialize(config, logger, metrics, redis_connection_pool, name, options)
|
18
18
|
@config = config
|
19
19
|
@logger = logger
|
20
20
|
@metrics = metrics
|
21
|
+
@redis = redis_connection_pool
|
21
22
|
@provider_name = name
|
22
23
|
|
23
24
|
# Ensure that there is not a nil provider configuration
|
@@ -9,8 +9,8 @@ module Vmpooler
|
|
9
9
|
class Dummy < Vmpooler::PoolManager::Provider::Base
|
10
10
|
# Fake VM Provider for testing
|
11
11
|
|
12
|
-
def initialize(config, logger, metrics, name, options)
|
13
|
-
super(config, logger, metrics, name, options)
|
12
|
+
def initialize(config, logger, metrics, redis_connection_pool, name, options)
|
13
|
+
super(config, logger, metrics, redis_connection_pool, name, options)
|
14
14
|
dummyfilename = provider_config['filename']
|
15
15
|
|
16
16
|
# This initial_state option is only intended to be used by spec tests
|
@@ -9,8 +9,8 @@ module Vmpooler
|
|
9
9
|
# The connection_pool method is normally used only for testing
|
10
10
|
attr_reader :connection_pool
|
11
11
|
|
12
|
-
def initialize(config, logger, metrics, name, options)
|
13
|
-
super(config, logger, metrics, name, options)
|
12
|
+
def initialize(config, logger, metrics, redis_connection_pool, name, options)
|
13
|
+
super(config, logger, metrics, redis_connection_pool, name, options)
|
14
14
|
|
15
15
|
task_limit = global_config[:config].nil? || global_config[:config]['task_limit'].nil? ? 10 : global_config[:config]['task_limit'].to_i
|
16
16
|
# The default connection pool size is:
|
@@ -39,6 +39,7 @@ module Vmpooler
|
|
39
39
|
end
|
40
40
|
@provider_hosts = {}
|
41
41
|
@provider_hosts_lock = Mutex.new
|
42
|
+
@redis = redis_connection_pool
|
42
43
|
end
|
43
44
|
|
44
45
|
# name of the provider class
|
@@ -59,12 +60,16 @@ module Vmpooler
|
|
59
60
|
def destroy_vm_and_log(vm_name, vm_object, pool, data_ttl)
|
60
61
|
try = 0 if try.nil?
|
61
62
|
max_tries = 3
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
63
|
+
@redis.with_metrics do |redis|
|
64
|
+
redis.multi
|
65
|
+
redis.srem("vmpooler__completed__#{pool}", vm_name)
|
66
|
+
redis.hdel("vmpooler__active__#{pool}", vm_name)
|
67
|
+
redis.hset("vmpooler__vm__#{vm_name}", 'destroy', Time.now)
|
68
|
+
|
69
|
+
# Auto-expire metadata key
|
70
|
+
redis.expire('vmpooler__vm__' + vm_name, (data_ttl * 60 * 60))
|
71
|
+
redis.exec
|
72
|
+
end
|
68
73
|
|
69
74
|
start = Time.now
|
70
75
|
|
@@ -343,7 +348,7 @@ module Vmpooler
|
|
343
348
|
|
344
349
|
begin
|
345
350
|
vm_target_folder = find_vm_folder(pool_name, connection)
|
346
|
-
vm_target_folder
|
351
|
+
vm_target_folder ||= create_folder(connection, target_folder_path, target_datacenter_name) if @config[:config].key?('create_folders') && (@config[:config]['create_folders'] == true)
|
347
352
|
rescue StandardError
|
348
353
|
if @config[:config].key?('create_folders') && (@config[:config]['create_folders'] == true)
|
349
354
|
vm_target_folder = create_folder(connection, target_folder_path, target_datacenter_name)
|
@@ -351,6 +356,7 @@ module Vmpooler
|
|
351
356
|
raise
|
352
357
|
end
|
353
358
|
end
|
359
|
+
raise ArgumentError, "Can not find the configured folder for #{pool_name} #{target_folder_path}" unless vm_target_folder
|
354
360
|
|
355
361
|
# Create the new VM
|
356
362
|
new_vm_object = template_vm_object.CloneVM_Task(
|
@@ -968,22 +974,24 @@ module Vmpooler
|
|
968
974
|
begin
|
969
975
|
connection = ensured_vsphere_connection(pool_object)
|
970
976
|
vm_hash = get_vm_details(pool_name, vm_name, connection)
|
971
|
-
|
972
|
-
|
973
|
-
|
974
|
-
|
975
|
-
if
|
976
|
-
|
977
|
-
|
978
|
-
|
979
|
-
|
980
|
-
|
981
|
-
|
977
|
+
@redis.with_metrics do |redis|
|
978
|
+
redis.hset("vmpooler__vm__#{vm_name}", 'host', vm_hash['host_name'])
|
979
|
+
migration_count = redis.scard('vmpooler__migration')
|
980
|
+
migration_limit = @config[:config]['migration_limit'] if @config[:config].key?('migration_limit')
|
981
|
+
if migration_enabled? @config
|
982
|
+
if migration_count >= migration_limit
|
983
|
+
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")
|
984
|
+
break
|
985
|
+
end
|
986
|
+
run_select_hosts(pool_name, @provider_hosts)
|
987
|
+
if vm_in_target?(pool_name, vm_hash['host_name'], vm_hash['architecture'], @provider_hosts)
|
988
|
+
logger.log('s', "[ ] [#{pool_name}] No migration required for '#{vm_name}' running on #{vm_hash['host_name']}")
|
989
|
+
else
|
990
|
+
migrate_vm_to_new_host(pool_name, vm_name, vm_hash, connection)
|
991
|
+
end
|
982
992
|
else
|
983
|
-
|
993
|
+
logger.log('s', "[ ] [#{pool_name}] '#{vm_name}' is running on #{vm_hash['host_name']}")
|
984
994
|
end
|
985
|
-
else
|
986
|
-
logger.log('s', "[ ] [#{pool_name}] '#{vm_name}' is running on #{vm_hash['host_name']}")
|
987
995
|
end
|
988
996
|
rescue StandardError
|
989
997
|
logger.log('s', "[!] [#{pool_name}] '#{vm_name}' is running on #{vm_hash['host_name']}")
|
@@ -993,15 +1001,23 @@ module Vmpooler
|
|
993
1001
|
end
|
994
1002
|
|
995
1003
|
def migrate_vm_to_new_host(pool_name, vm_name, vm_hash, connection)
|
996
|
-
|
1004
|
+
@redis.with_metrics do |redis|
|
1005
|
+
redis.sadd('vmpooler__migration', vm_name)
|
1006
|
+
end
|
997
1007
|
target_host_name = select_next_host(pool_name, @provider_hosts, vm_hash['architecture'])
|
998
1008
|
target_host_object = find_host_by_dnsname(connection, target_host_name)
|
999
1009
|
finish = migrate_vm_and_record_timing(pool_name, vm_name, vm_hash, target_host_object, target_host_name)
|
1000
|
-
|
1001
|
-
|
1010
|
+
@redis.with_metrics do |redis|
|
1011
|
+
redis.multi
|
1012
|
+
redis.hset("vmpooler__vm__#{vm_name}", 'host', target_host_name)
|
1013
|
+
redis.hset("vmpooler__vm__#{vm_name}", 'migrated', true)
|
1014
|
+
redis.exec
|
1015
|
+
end
|
1002
1016
|
logger.log('s', "[>] [#{pool_name}] '#{vm_name}' migrated from #{vm_hash['host_name']} to #{target_host_name} in #{finish} seconds")
|
1003
1017
|
ensure
|
1004
|
-
|
1018
|
+
@redis.with_metrics do |redis|
|
1019
|
+
redis.srem('vmpooler__migration', vm_name)
|
1020
|
+
end
|
1005
1021
|
end
|
1006
1022
|
|
1007
1023
|
def migrate_vm_and_record_timing(pool_name, vm_name, vm_hash, target_host_object, dest_host_name)
|
@@ -1011,9 +1027,13 @@ module Vmpooler
|
|
1011
1027
|
metrics.timing("migrate.#{pool_name}", finish)
|
1012
1028
|
metrics.increment("migrate_from.#{vm_hash['host_name']}")
|
1013
1029
|
metrics.increment("migrate_to.#{dest_host_name}")
|
1014
|
-
|
1015
|
-
|
1016
|
-
|
1030
|
+
@redis.with_metrics do |redis|
|
1031
|
+
checkout_to_migration = format('%<time>.2f', time: Time.now - Time.parse(redis.hget("vmpooler__vm__#{vm_name}", 'checkout')))
|
1032
|
+
redis.multi
|
1033
|
+
redis.hset("vmpooler__vm__#{vm_name}", 'migration_time', finish)
|
1034
|
+
redis.hset("vmpooler__vm__#{vm_name}", 'checkout_to_migration', checkout_to_migration)
|
1035
|
+
redis.exec
|
1036
|
+
end
|
1017
1037
|
finish
|
1018
1038
|
end
|
1019
1039
|
|
data/lib/vmpooler/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: vmpooler
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.13.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Puppet
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-06-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: pickup
|
@@ -150,6 +150,20 @@ dependencies:
|
|
150
150
|
- - "~>"
|
151
151
|
- !ruby/object:Gem::Version
|
152
152
|
version: '2.2'
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: concurrent-ruby
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - "~>"
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '1.1'
|
160
|
+
type: :runtime
|
161
|
+
prerelease: false
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - "~>"
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '1.1'
|
153
167
|
- !ruby/object:Gem::Dependency
|
154
168
|
name: nokogiri
|
155
169
|
requirement: !ruby/object:Gem::Requirement
|