vmpooler 1.2.0 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/vmpooler/api/v1.rb +97 -0
- data/lib/vmpooler/pool_manager.rb +53 -6
- data/lib/vmpooler/version.rb +1 -1
- data/lib/vmpooler.rb +9 -0
- metadata +22 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 32b41fec26ba54f25cb6186a6dc1b97904a855f0e5ceeca19978c4c614b5ef55
|
4
|
+
data.tar.gz: 1937db66b56b998fe4030ed133eaad5bbabd15646d3786dfa1539a8ee6e35a95
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 747e7156ec196e938a41ffcc7857d01c32d9412b28ce20bea8f52edc6d6579118c7f4d458bdca70d8765b1ce081e44926b0c5560081e6fa27d74110262ce1e2d
|
7
|
+
data.tar.gz: e77c0fe360af30347f20ada5cd34879087b4775aff81914ee41c83639d7a9c91951dc8a5cbf0f2028eabd65312d96e94a95bcc81457de3d1c897d121a79282c2
|
data/lib/vmpooler/api/v1.rb
CHANGED
@@ -28,6 +28,10 @@ module Vmpooler
|
|
28
28
|
Vmpooler::API.settings.config[:pools]
|
29
29
|
end
|
30
30
|
|
31
|
+
def pools_at_startup
|
32
|
+
Vmpooler::API.settings.config[:pools_at_startup]
|
33
|
+
end
|
34
|
+
|
31
35
|
def pool_exists?(template)
|
32
36
|
Vmpooler::API.settings.config[:pool_names].include?(template)
|
33
37
|
end
|
@@ -289,6 +293,32 @@ module Vmpooler
|
|
289
293
|
puts 'd', "[!] [#{poolname}] failed while evaluating usage labels on '#{vmname}' with an error: #{e}"
|
290
294
|
end
|
291
295
|
|
296
|
+
def reset_pool_size(poolname)
|
297
|
+
result = { 'ok' => false }
|
298
|
+
|
299
|
+
pool_index = pool_index(pools)
|
300
|
+
|
301
|
+
pools_updated = 0
|
302
|
+
sync_pool_sizes
|
303
|
+
|
304
|
+
pool_size_now = pools[pool_index[poolname]]['size'].to_i
|
305
|
+
pool_size_original = pools_at_startup[pool_index[poolname]]['size'].to_i
|
306
|
+
result['pool_size_before_reset'] = pool_size_now
|
307
|
+
result['pool_size_before_overrides'] = pool_size_original
|
308
|
+
|
309
|
+
unless pool_size_now == pool_size_original
|
310
|
+
pools[pool_index[poolname]]['size'] = pool_size_original
|
311
|
+
backend.hdel('vmpooler__config__poolsize', poolname)
|
312
|
+
backend.sadd('vmpooler__pool__undo_size_override', poolname)
|
313
|
+
pools_updated += 1
|
314
|
+
status 201
|
315
|
+
end
|
316
|
+
|
317
|
+
status 200 unless pools_updated > 0
|
318
|
+
result['ok'] = true
|
319
|
+
result
|
320
|
+
end
|
321
|
+
|
292
322
|
def update_pool_size(payload)
|
293
323
|
result = { 'ok' => false }
|
294
324
|
|
@@ -309,6 +339,33 @@ module Vmpooler
|
|
309
339
|
result
|
310
340
|
end
|
311
341
|
|
342
|
+
def reset_pool_template(poolname)
|
343
|
+
result = { 'ok' => false }
|
344
|
+
|
345
|
+
pool_index_live = pool_index(pools)
|
346
|
+
pool_index_original = pool_index(pools_at_startup)
|
347
|
+
|
348
|
+
pools_updated = 0
|
349
|
+
sync_pool_templates
|
350
|
+
|
351
|
+
template_now = pools[pool_index_live[poolname]]['template']
|
352
|
+
template_original = pools_at_startup[pool_index_original[poolname]]['template']
|
353
|
+
result['template_before_reset'] = template_now
|
354
|
+
result['template_before_overrides'] = template_original
|
355
|
+
|
356
|
+
unless template_now == template_original
|
357
|
+
pools[pool_index_live[poolname]]['template'] = template_original
|
358
|
+
backend.hdel('vmpooler__config__template', poolname)
|
359
|
+
backend.sadd('vmpooler__pool__undo_template_override', poolname)
|
360
|
+
pools_updated += 1
|
361
|
+
status 201
|
362
|
+
end
|
363
|
+
|
364
|
+
status 200 unless pools_updated > 0
|
365
|
+
result['ok'] = true
|
366
|
+
result
|
367
|
+
end
|
368
|
+
|
312
369
|
def update_pool_template(payload)
|
313
370
|
result = { 'ok' => false }
|
314
371
|
|
@@ -1375,6 +1432,26 @@ module Vmpooler
|
|
1375
1432
|
JSON.pretty_generate(result)
|
1376
1433
|
end
|
1377
1434
|
|
1435
|
+
delete "#{api_prefix}/config/poolsize/:pool/?" do
|
1436
|
+
content_type :json
|
1437
|
+
result = { 'ok' => false }
|
1438
|
+
|
1439
|
+
if config['experimental_features']
|
1440
|
+
need_token! if Vmpooler::API.settings.config[:auth]
|
1441
|
+
|
1442
|
+
if pool_exists?(params[:pool])
|
1443
|
+
result = reset_pool_size(params[:pool])
|
1444
|
+
else
|
1445
|
+
metrics.increment('config.invalid.unknown')
|
1446
|
+
status 404
|
1447
|
+
end
|
1448
|
+
else
|
1449
|
+
status 405
|
1450
|
+
end
|
1451
|
+
|
1452
|
+
JSON.pretty_generate(result)
|
1453
|
+
end
|
1454
|
+
|
1378
1455
|
post "#{api_prefix}/config/poolsize/?" do
|
1379
1456
|
content_type :json
|
1380
1457
|
result = { 'ok' => false }
|
@@ -1406,6 +1483,26 @@ module Vmpooler
|
|
1406
1483
|
JSON.pretty_generate(result)
|
1407
1484
|
end
|
1408
1485
|
|
1486
|
+
delete "#{api_prefix}/config/pooltemplate/:pool/?" do
|
1487
|
+
content_type :json
|
1488
|
+
result = { 'ok' => false }
|
1489
|
+
|
1490
|
+
if config['experimental_features']
|
1491
|
+
need_token! if Vmpooler::API.settings.config[:auth]
|
1492
|
+
|
1493
|
+
if pool_exists?(params[:pool])
|
1494
|
+
result = reset_pool_template(params[:pool])
|
1495
|
+
else
|
1496
|
+
metrics.increment('config.invalid.unknown')
|
1497
|
+
status 404
|
1498
|
+
end
|
1499
|
+
else
|
1500
|
+
status 405
|
1501
|
+
end
|
1502
|
+
|
1503
|
+
JSON.pretty_generate(result)
|
1504
|
+
end
|
1505
|
+
|
1409
1506
|
post "#{api_prefix}/config/pooltemplate/?" do
|
1410
1507
|
content_type :json
|
1411
1508
|
result = { 'ok' => false }
|
@@ -784,6 +784,10 @@ module Vmpooler
|
|
784
784
|
# - Fires when a pool reset is requested
|
785
785
|
# - Additional options
|
786
786
|
# :poolname
|
787
|
+
# :undo_override
|
788
|
+
# - Fires when a pool override removal is requested
|
789
|
+
# - Additional options
|
790
|
+
# :poolname
|
787
791
|
#
|
788
792
|
def sleep_with_wakeup_events(loop_delay, wakeup_period = 5, options = {})
|
789
793
|
exit_by = Time.now + loop_delay
|
@@ -826,6 +830,11 @@ module Vmpooler
|
|
826
830
|
break if pending
|
827
831
|
end
|
828
832
|
|
833
|
+
if options[:undo_override]
|
834
|
+
break if redis.sismember('vmpooler__pool__undo_template_override', options[:poolname])
|
835
|
+
break if redis.sismember('vmpooler__pool__undo_size_override', options[:poolname])
|
836
|
+
end
|
837
|
+
|
829
838
|
if options[:pending_vm]
|
830
839
|
pending_vm_count = redis.scard("vmpooler__pending__#{options[:poolname]}")
|
831
840
|
break unless pending_vm_count == 0
|
@@ -880,7 +889,7 @@ module Vmpooler
|
|
880
889
|
loop_delay = (loop_delay * loop_delay_decay).to_i
|
881
890
|
loop_delay = loop_delay_max if loop_delay > loop_delay_max
|
882
891
|
end
|
883
|
-
sleep_with_wakeup_events(loop_delay, loop_delay_min, pool_size_change: true, poolname: pool['name'], pool_template_change: true, clone_target_change: true, pending_vm: true, pool_reset: true)
|
892
|
+
sleep_with_wakeup_events(loop_delay, loop_delay_min, pool_size_change: true, poolname: pool['name'], pool_template_change: true, clone_target_change: true, pending_vm: true, pool_reset: true, undo_override: true)
|
884
893
|
|
885
894
|
unless maxloop == 0
|
886
895
|
break if loop_count >= maxloop
|
@@ -1040,15 +1049,18 @@ module Vmpooler
|
|
1040
1049
|
return if mutex.locked?
|
1041
1050
|
|
1042
1051
|
@redis.with_metrics do |redis|
|
1043
|
-
|
1044
|
-
break if
|
1052
|
+
pool_size_requested = redis.hget('vmpooler__config__poolsize', pool['name'])
|
1053
|
+
break if pool_size_requested.nil?
|
1045
1054
|
|
1046
|
-
|
1047
|
-
|
1055
|
+
pool_size_requested = Integer(pool_size_requested)
|
1056
|
+
pool_size_currently = pool['size']
|
1057
|
+
break if pool_size_requested == pool_size_currently
|
1048
1058
|
|
1049
1059
|
mutex.synchronize do
|
1050
|
-
pool['size'] =
|
1060
|
+
pool['size'] = pool_size_requested
|
1051
1061
|
end
|
1062
|
+
|
1063
|
+
$logger.log('s', "[*] [#{pool['name']}] size updated from #{pool_size_currently} to #{pool_size_requested}")
|
1052
1064
|
end
|
1053
1065
|
end
|
1054
1066
|
|
@@ -1066,6 +1078,38 @@ module Vmpooler
|
|
1066
1078
|
end
|
1067
1079
|
end
|
1068
1080
|
|
1081
|
+
def undo_override(pool, provider)
|
1082
|
+
poolname = pool['name']
|
1083
|
+
mutex = pool_mutex(poolname)
|
1084
|
+
return if mutex.locked?
|
1085
|
+
|
1086
|
+
@redis.with_metrics do |redis|
|
1087
|
+
break unless redis.sismember('vmpooler__pool__undo_template_override', poolname)
|
1088
|
+
|
1089
|
+
redis.srem('vmpooler__pool__undo_template_override', poolname)
|
1090
|
+
template_now = pool['template']
|
1091
|
+
template_original = $config[:pools_at_startup][$config[:pool_index][poolname]]['template']
|
1092
|
+
|
1093
|
+
mutex.synchronize do
|
1094
|
+
update_pool_template(pool, provider, template_original, template_now, redis)
|
1095
|
+
end
|
1096
|
+
end
|
1097
|
+
|
1098
|
+
@redis.with_metrics do |redis|
|
1099
|
+
break unless redis.sismember('vmpooler__pool__undo_size_override', poolname)
|
1100
|
+
|
1101
|
+
redis.srem('vmpooler__pool__undo_size_override', poolname)
|
1102
|
+
pool_size_now = pool['size']
|
1103
|
+
pool_size_original = $config[:pools_at_startup][$config[:pool_index][poolname]]['size']
|
1104
|
+
|
1105
|
+
mutex.synchronize do
|
1106
|
+
pool['size'] = pool_size_original
|
1107
|
+
end
|
1108
|
+
|
1109
|
+
$logger.log('s', "[*] [#{poolname}] size updated from #{pool_size_now} to #{pool_size_original}")
|
1110
|
+
end
|
1111
|
+
end
|
1112
|
+
|
1069
1113
|
def create_inventory(pool, provider, pool_check_response)
|
1070
1114
|
inventory = {}
|
1071
1115
|
begin
|
@@ -1300,6 +1344,9 @@ module Vmpooler
|
|
1300
1344
|
# Reset a pool when poolreset is requested from the API
|
1301
1345
|
reset_pool(pool)
|
1302
1346
|
|
1347
|
+
# Undo overrides submitted via the api
|
1348
|
+
undo_override(pool, provider)
|
1349
|
+
|
1303
1350
|
pool_check_response
|
1304
1351
|
end
|
1305
1352
|
|
data/lib/vmpooler/version.rb
CHANGED
data/lib/vmpooler.rb
CHANGED
@@ -133,8 +133,17 @@ module Vmpooler
|
|
133
133
|
parsed_config[:pools] = load_pools_from_redis(redis)
|
134
134
|
end
|
135
135
|
|
136
|
+
# Marshal.dump is paired with Marshal.load to create a copy that has its own memory space
|
137
|
+
# so that each can be edited independently
|
138
|
+
# rubocop:disable Security/MarshalLoad
|
139
|
+
|
140
|
+
# retain a copy of the pools that were observed at startup
|
141
|
+
serialized_pools = Marshal.dump(parsed_config[:pools])
|
142
|
+
parsed_config[:pools_at_startup] = Marshal.load(serialized_pools)
|
143
|
+
|
136
144
|
# Create an index of pools by title
|
137
145
|
parsed_config[:pool_index] = pool_index(parsed_config[:pools])
|
146
|
+
# rubocop:enable Security/MarshalLoad
|
138
147
|
|
139
148
|
parsed_config[:pools].each do |pool|
|
140
149
|
parsed_config[:pool_names] << pool['name']
|
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: 1.
|
4
|
+
version: 1.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Puppet
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-11-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: concurrent-ruby
|
@@ -400,6 +400,26 @@ dependencies:
|
|
400
400
|
- - ">="
|
401
401
|
- !ruby/object:Gem::Version
|
402
402
|
version: 0.11.2
|
403
|
+
- !ruby/object:Gem::Dependency
|
404
|
+
name: thor
|
405
|
+
requirement: !ruby/object:Gem::Requirement
|
406
|
+
requirements:
|
407
|
+
- - "~>"
|
408
|
+
- !ruby/object:Gem::Version
|
409
|
+
version: '1.0'
|
410
|
+
- - ">="
|
411
|
+
- !ruby/object:Gem::Version
|
412
|
+
version: 1.0.1
|
413
|
+
type: :development
|
414
|
+
prerelease: false
|
415
|
+
version_requirements: !ruby/object:Gem::Requirement
|
416
|
+
requirements:
|
417
|
+
- - "~>"
|
418
|
+
- !ruby/object:Gem::Version
|
419
|
+
version: '1.0'
|
420
|
+
- - ">="
|
421
|
+
- !ruby/object:Gem::Version
|
422
|
+
version: 1.0.1
|
403
423
|
- !ruby/object:Gem::Dependency
|
404
424
|
name: yarjuf
|
405
425
|
requirement: !ruby/object:Gem::Requirement
|