vmpooler 1.2.0 → 1.3.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: da4a010ab09d34f4fbfa9993526ad18dec205dfbc72f427a250304b2147bdf31
4
- data.tar.gz: 61193bec61a1385754487f107e601c1fc76959ae81fc27a47d4f11a881553e91
3
+ metadata.gz: 32b41fec26ba54f25cb6186a6dc1b97904a855f0e5ceeca19978c4c614b5ef55
4
+ data.tar.gz: 1937db66b56b998fe4030ed133eaad5bbabd15646d3786dfa1539a8ee6e35a95
5
5
  SHA512:
6
- metadata.gz: 13399e493bcaaf5c18541c2125366bb88325936746b715550c6e438d31de77eed9b0f42d9e6140c7529eb0dbd27e4335529f368e6b190c1d047f0cd2710f801e
7
- data.tar.gz: 0f8551abcbb4cfbaf7bbf60d52f6630ce8334fff620ef1e05bad35e53fb7448c69da074494f8df5efa97053ad6b1e3dd2e55c942e97b359156b0ec07b26de912
6
+ metadata.gz: 747e7156ec196e938a41ffcc7857d01c32d9412b28ce20bea8f52edc6d6579118c7f4d458bdca70d8765b1ce081e44926b0c5560081e6fa27d74110262ce1e2d
7
+ data.tar.gz: e77c0fe360af30347f20ada5cd34879087b4775aff81914ee41c83639d7a9c91951dc8a5cbf0f2028eabd65312d96e94a95bcc81457de3d1c897d121a79282c2
@@ -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
- poolsize = redis.hget('vmpooler__config__poolsize', pool['name'])
1044
- break if poolsize.nil?
1052
+ pool_size_requested = redis.hget('vmpooler__config__poolsize', pool['name'])
1053
+ break if pool_size_requested.nil?
1045
1054
 
1046
- poolsize = Integer(poolsize)
1047
- break if poolsize == pool['size']
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'] = poolsize
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
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Vmpooler
4
- VERSION = '1.2.0'
4
+ VERSION = '1.3.0'
5
5
  end
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.2.0
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-09-15 00:00:00.000000000 Z
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