vmpooler 0.12.0 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/bin/vmpooler +3 -1
- data/lib/vmpooler.rb +23 -1
- data/lib/vmpooler/api/helpers.rb +1 -1
- data/lib/vmpooler/api/v1.rb +285 -17
- data/lib/vmpooler/generic_connection_pool.rb +5 -23
- 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.0
|
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-04 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
|