vmpooler 0.10.3 → 0.12.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 +2 -3
- data/lib/vmpooler.rb +20 -11
- data/lib/vmpooler/api.rb +2 -0
- data/lib/vmpooler/api/dashboard.rb +12 -5
- data/lib/vmpooler/api/helpers.rb +49 -44
- data/lib/vmpooler/api/reroute.rb +2 -0
- data/lib/vmpooler/api/v1.rb +58 -58
- data/lib/vmpooler/dashboard.rb +2 -1
- data/lib/vmpooler/dummy_statsd.rb +2 -0
- data/lib/vmpooler/generic_connection_pool.rb +8 -6
- data/lib/vmpooler/graphite.rb +5 -5
- data/lib/vmpooler/logger.rb +3 -1
- data/lib/vmpooler/pool_manager.rb +143 -126
- data/lib/vmpooler/providers.rb +13 -15
- data/lib/vmpooler/providers/base.rb +5 -3
- data/lib/vmpooler/providers/dummy.rb +16 -12
- data/lib/vmpooler/providers/vsphere.rb +118 -99
- data/lib/vmpooler/statsd.rb +9 -9
- data/lib/vmpooler/version.rb +3 -1
- metadata +14 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 19dd8ce83614c49e92f13e043c2ee7865f1c664d92aa8f13e47fc328eb033690
|
4
|
+
data.tar.gz: c3618c9c13591b1b06748ac3e5d1c2dc7ba2eb9793ea2f3f014a762fd6deb4ed
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8dcb8f8765f9c1fac52c2d0088aaa09a589b5145d5a81e901af614b8fcbbd588669b3f14e5c42f4d56d4681165f8814ef11b22073df6f97b85cef6fcb10d04e2
|
7
|
+
data.tar.gz: d7c917233daee973486a6a8add55222a92bb1708521caaefdf2666824c0785cebd1ce7e298448a66736bf7e0646f02a560067e54cc1d06a07ca6abae645898c9
|
data/bin/vmpooler
CHANGED
data/lib/vmpooler.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Vmpooler
|
2
4
|
require 'date'
|
3
5
|
require 'json'
|
@@ -27,13 +29,21 @@ module Vmpooler
|
|
27
29
|
# Take the name of the config file either from an ENV variable or from the filepath argument
|
28
30
|
config_file = ENV['VMPOOLER_CONFIG_FILE'] || filepath
|
29
31
|
parsed_config = YAML.load_file(config_file) if File.exist? config_file
|
32
|
+
parsed_config[:config]['extra_config'] = ENV['EXTRA_CONFIG'] if ENV['EXTRA_CONFIG']
|
33
|
+
if parsed_config[:config]['extra_config']
|
34
|
+
extra_configs = parsed_config[:config]['extra_config'].split(',')
|
35
|
+
extra_configs.each do |config|
|
36
|
+
extra_config = YAML.load_file(config)
|
37
|
+
parsed_config.merge!(extra_config)
|
38
|
+
end
|
39
|
+
end
|
30
40
|
end
|
31
41
|
|
32
42
|
parsed_config ||= { config: {} }
|
33
43
|
|
34
44
|
# Bail out if someone attempts to start vmpooler with dummy authentication
|
35
45
|
# without enbaling debug mode.
|
36
|
-
if parsed_config.
|
46
|
+
if parsed_config.key? :auth
|
37
47
|
if parsed_config[:auth]['provider'] == 'dummy'
|
38
48
|
unless ENV['VMPOOLER_DEBUG']
|
39
49
|
warning = [
|
@@ -50,7 +60,7 @@ module Vmpooler
|
|
50
60
|
parsed_config[:config]['task_limit'] = string_to_int(ENV['TASK_LIMIT']) || parsed_config[:config]['task_limit'] || 10
|
51
61
|
parsed_config[:config]['migration_limit'] = string_to_int(ENV['MIGRATION_LIMIT']) if ENV['MIGRATION_LIMIT']
|
52
62
|
parsed_config[:config]['vm_checktime'] = string_to_int(ENV['VM_CHECKTIME']) || parsed_config[:config]['vm_checktime'] || 1
|
53
|
-
parsed_config[:config]['vm_lifetime'] = string_to_int(ENV['VM_LIFETIME']) || parsed_config[:config]['vm_lifetime']
|
63
|
+
parsed_config[:config]['vm_lifetime'] = string_to_int(ENV['VM_LIFETIME']) || parsed_config[:config]['vm_lifetime'] || 24
|
54
64
|
parsed_config[:config]['prefix'] = ENV['PREFIX'] || parsed_config[:config]['prefix'] || ''
|
55
65
|
|
56
66
|
parsed_config[:config]['logfile'] = ENV['LOGFILE'] if ENV['LOGFILE']
|
@@ -86,7 +96,7 @@ module Vmpooler
|
|
86
96
|
parsed_config[:graphite]['port'] = string_to_int(ENV['GRAPHITE_PORT']) if ENV['GRAPHITE_PORT']
|
87
97
|
|
88
98
|
parsed_config[:auth] = parsed_config[:auth] || {} if ENV['AUTH_PROVIDER']
|
89
|
-
if parsed_config.
|
99
|
+
if parsed_config.key? :auth
|
90
100
|
parsed_config[:auth]['provider'] = ENV['AUTH_PROVIDER'] if ENV['AUTH_PROVIDER']
|
91
101
|
parsed_config[:auth][:ldap] = parsed_config[:auth][:ldap] || {} if parsed_config[:auth]['provider'] == 'ldap'
|
92
102
|
parsed_config[:auth][:ldap]['host'] = ENV['LDAP_HOST'] if ENV['LDAP_HOST']
|
@@ -122,10 +132,8 @@ module Vmpooler
|
|
122
132
|
end
|
123
133
|
end
|
124
134
|
|
125
|
-
|
126
|
-
parsed_config[:tagfilter]
|
127
|
-
parsed_config[:tagfilter][tag] = Regexp.new(parsed_config[:tagfilter][tag])
|
128
|
-
end
|
135
|
+
parsed_config[:tagfilter]&.keys&.each do |tag|
|
136
|
+
parsed_config[:tagfilter][tag] = Regexp.new(parsed_config[:tagfilter][tag])
|
129
137
|
end
|
130
138
|
|
131
139
|
parsed_config[:uptime] = Time.now
|
@@ -171,7 +179,7 @@ module Vmpooler
|
|
171
179
|
def self.pool_index(pools)
|
172
180
|
pools_hash = {}
|
173
181
|
index = 0
|
174
|
-
|
182
|
+
pools.each do |pool|
|
175
183
|
pools_hash[pool['name']] = index
|
176
184
|
index += 1
|
177
185
|
end
|
@@ -182,14 +190,15 @@ module Vmpooler
|
|
182
190
|
# Returns a integer if input is a string
|
183
191
|
return if s.nil?
|
184
192
|
return unless s =~ /\d/
|
185
|
-
|
193
|
+
|
194
|
+
Integer(s)
|
186
195
|
end
|
187
196
|
|
188
197
|
def self.true?(obj)
|
189
|
-
obj.to_s.downcase ==
|
198
|
+
obj.to_s.downcase == 'true'
|
190
199
|
end
|
191
200
|
|
192
|
-
def self.set_linked_clone(parsed_config)
|
201
|
+
def self.set_linked_clone(parsed_config) # rubocop:disable Naming/AccessorMethodName
|
193
202
|
parsed_config[:config]['create_linked_clones'] = parsed_config[:config]['create_linked_clones'] || true
|
194
203
|
parsed_config[:config]['create_linked_clones'] = ENV['CREATE_LINKED_CLONES'] if ENV['CREATE_LINKED_CLONES'] =~ /true|false/
|
195
204
|
parsed_config[:config]['create_linked_clones'] = true?(parsed_config[:config]['create_linked_clones']) if parsed_config[:config]['create_linked_clones']
|
data/lib/vmpooler/api.rb
CHANGED
@@ -1,7 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Vmpooler
|
2
4
|
class API
|
3
5
|
class Dashboard < Sinatra::Base
|
4
|
-
|
5
6
|
helpers do
|
6
7
|
include Vmpooler::API::Helpers
|
7
8
|
end
|
@@ -21,9 +22,11 @@ module Vmpooler
|
|
21
22
|
|
22
23
|
if config[:graphs]
|
23
24
|
return false unless config[:graphs]['server']
|
25
|
+
|
24
26
|
@graph_server = config[:graphs]['server']
|
25
27
|
elsif config[:graphite]
|
26
28
|
return false unless config[:graphite]['server']
|
29
|
+
|
27
30
|
@graph_server = config[:graphite]['server']
|
28
31
|
else
|
29
32
|
false
|
@@ -36,9 +39,11 @@ module Vmpooler
|
|
36
39
|
|
37
40
|
if config[:graphs]
|
38
41
|
return 'vmpooler' unless config[:graphs]['prefix']
|
42
|
+
|
39
43
|
@graph_prefix = config[:graphs]['prefix']
|
40
44
|
elsif config[:graphite]
|
41
45
|
return false unless config[:graphite]['prefix']
|
46
|
+
|
42
47
|
@graph_prefix = config[:graphite]['prefix']
|
43
48
|
else
|
44
49
|
false
|
@@ -48,12 +53,14 @@ module Vmpooler
|
|
48
53
|
# what is the base URL for viewable graphs?
|
49
54
|
def graph_url
|
50
55
|
return false unless graph_server && graph_prefix
|
56
|
+
|
51
57
|
@graph_url ||= "http://#{graph_server}/render?target=#{graph_prefix}"
|
52
58
|
end
|
53
59
|
|
54
60
|
# return a full URL to a viewable graph for a given metrics target (graphite syntax)
|
55
61
|
def graph_link(target = '')
|
56
62
|
return '' unless graph_url
|
63
|
+
|
57
64
|
graph_url + target
|
58
65
|
end
|
59
66
|
|
@@ -76,7 +83,7 @@ module Vmpooler
|
|
76
83
|
history ||= {}
|
77
84
|
|
78
85
|
begin
|
79
|
-
buffer =
|
86
|
+
buffer = URI.parse(graph_link('.ready.*&from=-1hour&format=json')).read
|
80
87
|
history = JSON.parse(buffer)
|
81
88
|
|
82
89
|
history.each do |pool|
|
@@ -100,7 +107,7 @@ module Vmpooler
|
|
100
107
|
end
|
101
108
|
end
|
102
109
|
end
|
103
|
-
rescue
|
110
|
+
rescue StandardError
|
104
111
|
end
|
105
112
|
else
|
106
113
|
pools.each do |pool|
|
@@ -129,7 +136,7 @@ module Vmpooler
|
|
129
136
|
if params[:history]
|
130
137
|
if graph_url
|
131
138
|
begin
|
132
|
-
buffer =
|
139
|
+
buffer = URI.parse(graph_link('.running.*&from=-1hour&format=json')).read
|
133
140
|
JSON.parse(buffer).each do |pool|
|
134
141
|
if pool['target'] =~ /.*\.(.*)$/
|
135
142
|
pool['name'] = Regexp.last_match[1]
|
@@ -147,7 +154,7 @@ module Vmpooler
|
|
147
154
|
end
|
148
155
|
end
|
149
156
|
end
|
150
|
-
rescue
|
157
|
+
rescue StandardError
|
151
158
|
end
|
152
159
|
end
|
153
160
|
end
|
data/lib/vmpooler/api/helpers.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Vmpooler
|
2
4
|
|
3
5
|
class API
|
@@ -71,43 +73,44 @@ module Vmpooler
|
|
71
73
|
)
|
72
74
|
|
73
75
|
return true if ldap.bind
|
76
|
+
|
74
77
|
return false
|
75
78
|
end
|
76
79
|
|
77
80
|
def authenticate(auth, username_str, password_str)
|
78
81
|
case auth['provider']
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
else
|
82
|
+
when 'dummy'
|
83
|
+
return (username_str != password_str)
|
84
|
+
when 'ldap'
|
85
|
+
ldap_base = auth[:ldap]['base']
|
86
|
+
ldap_port = auth[:ldap]['port'] || 389
|
87
|
+
ldap_user_obj = auth[:ldap]['user_object']
|
88
|
+
ldap_host = auth[:ldap]['host']
|
89
|
+
|
90
|
+
unless ldap_base.is_a? Array
|
91
|
+
ldap_base = ldap_base.split
|
92
|
+
end
|
93
|
+
|
94
|
+
unless ldap_user_obj.is_a? Array
|
95
|
+
ldap_user_obj = ldap_user_obj.split
|
96
|
+
end
|
97
|
+
|
98
|
+
ldap_base.each do |search_base|
|
99
|
+
ldap_user_obj.each do |search_user_obj|
|
98
100
|
result = authenticate_ldap(
|
99
101
|
ldap_port,
|
100
|
-
|
101
|
-
|
102
|
-
|
102
|
+
ldap_host,
|
103
|
+
search_user_obj,
|
104
|
+
search_base,
|
103
105
|
username_str,
|
104
|
-
password_str
|
106
|
+
password_str
|
105
107
|
)
|
106
|
-
return result
|
108
|
+
return true if result
|
107
109
|
end
|
108
|
-
|
109
|
-
return false
|
110
110
|
end
|
111
|
+
|
112
|
+
return false
|
113
|
+
end
|
111
114
|
end
|
112
115
|
|
113
116
|
def export_tags(backend, hostname, tags)
|
@@ -124,6 +127,7 @@ module Vmpooler
|
|
124
127
|
|
125
128
|
tags.each_pair do |tag, value|
|
126
129
|
next unless filter = Vmpooler::API.settings.config[:tagfilter][tag]
|
130
|
+
|
127
131
|
tags[tag] = value.match(filter).captures.join if value.match(filter)
|
128
132
|
end
|
129
133
|
|
@@ -161,7 +165,7 @@ module Vmpooler
|
|
161
165
|
backend.scard(key + pool['name'])
|
162
166
|
end
|
163
167
|
end
|
164
|
-
res.inject(0){ |m, x| m+x }.to_i
|
168
|
+
res.inject(0) { |m, x| m + x }.to_i
|
165
169
|
end
|
166
170
|
|
167
171
|
# Takes the pools and a key to run scard on
|
@@ -201,18 +205,18 @@ module Vmpooler
|
|
201
205
|
def get_capacity_metrics(pools, backend)
|
202
206
|
capacity = {
|
203
207
|
current: 0,
|
204
|
-
total:
|
208
|
+
total: 0,
|
205
209
|
percent: 0
|
206
210
|
}
|
207
211
|
|
208
212
|
pools.each do |pool|
|
209
|
-
capacity[:total]
|
213
|
+
capacity[:total] += pool['size'].to_i
|
210
214
|
end
|
211
215
|
|
212
216
|
capacity[:current] = get_total_across_pools_redis_scard(pools, 'vmpooler__ready__', backend)
|
213
217
|
|
214
218
|
if capacity[:total] > 0
|
215
|
-
capacity[:percent] = (
|
219
|
+
capacity[:percent] = (capacity[:current].fdiv(capacity[:total]) * 100.0).round(1)
|
216
220
|
end
|
217
221
|
|
218
222
|
capacity
|
@@ -220,16 +224,16 @@ module Vmpooler
|
|
220
224
|
|
221
225
|
def get_queue_metrics(pools, backend)
|
222
226
|
queue = {
|
223
|
-
pending:
|
224
|
-
cloning:
|
225
|
-
booting:
|
226
|
-
ready:
|
227
|
-
running:
|
227
|
+
pending: 0,
|
228
|
+
cloning: 0,
|
229
|
+
booting: 0,
|
230
|
+
ready: 0,
|
231
|
+
running: 0,
|
228
232
|
completed: 0,
|
229
|
-
total:
|
233
|
+
total: 0
|
230
234
|
}
|
231
235
|
|
232
|
-
queue[:pending] = get_total_across_pools_redis_scard(pools,'vmpooler__pending__', backend)
|
236
|
+
queue[:pending] = get_total_across_pools_redis_scard(pools, 'vmpooler__pending__', backend)
|
233
237
|
queue[:ready] = get_total_across_pools_redis_scard(pools, 'vmpooler__ready__', backend)
|
234
238
|
queue[:running] = get_total_across_pools_redis_scard(pools, 'vmpooler__running__', backend)
|
235
239
|
queue[:completed] = get_total_across_pools_redis_scard(pools, 'vmpooler__completed__', backend)
|
@@ -306,11 +310,11 @@ module Vmpooler
|
|
306
310
|
task = {
|
307
311
|
duration: {
|
308
312
|
average: 0,
|
309
|
-
min:
|
310
|
-
max:
|
311
|
-
total:
|
313
|
+
min: 0,
|
314
|
+
max: 0,
|
315
|
+
total: 0
|
312
316
|
},
|
313
|
-
count:
|
317
|
+
count: {
|
314
318
|
total: 0
|
315
319
|
}
|
316
320
|
}
|
@@ -450,7 +454,7 @@ module Vmpooler
|
|
450
454
|
def pool_index(pools)
|
451
455
|
pools_hash = {}
|
452
456
|
index = 0
|
453
|
-
|
457
|
+
pools.each do |pool|
|
454
458
|
pools_hash[pool['name']] = index
|
455
459
|
index += 1
|
456
460
|
end
|
@@ -461,13 +465,14 @@ module Vmpooler
|
|
461
465
|
prepared_template = backend.hget('vmpooler__template__prepared', pool['name'])
|
462
466
|
return false if prepared_template.nil?
|
463
467
|
return true if pool['template'] == prepared_template
|
468
|
+
|
464
469
|
return false
|
465
470
|
end
|
466
471
|
|
467
472
|
def is_integer?(x)
|
468
473
|
Integer(x)
|
469
474
|
true
|
470
|
-
rescue
|
475
|
+
rescue StandardError
|
471
476
|
false
|
472
477
|
end
|
473
478
|
|
@@ -487,7 +492,7 @@ module Vmpooler
|
|
487
492
|
def vm_ready?(vm_name, domain = nil)
|
488
493
|
begin
|
489
494
|
open_socket(vm_name, domain)
|
490
|
-
rescue =>
|
495
|
+
rescue StandardError => _e
|
491
496
|
return false
|
492
497
|
end
|
493
498
|
|
data/lib/vmpooler/api/reroute.rb
CHANGED
data/lib/vmpooler/api/v1.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Vmpooler
|
2
4
|
class API
|
3
5
|
class V1 < Sinatra::Base
|
@@ -37,22 +39,24 @@ module Vmpooler
|
|
37
39
|
end
|
38
40
|
|
39
41
|
def checkoutlock
|
40
|
-
Vmpooler::API
|
42
|
+
Vmpooler::API.settings.checkoutlock
|
41
43
|
end
|
42
44
|
|
43
45
|
def fetch_single_vm(template)
|
44
46
|
template_backends = [template]
|
45
47
|
aliases = Vmpooler::API.settings.config[:alias]
|
46
48
|
if aliases
|
47
|
-
template_backends
|
49
|
+
template_backends += aliases[template] if aliases[template].is_a?(Array)
|
48
50
|
template_backends << aliases[template] if aliases[template].is_a?(String)
|
49
51
|
pool_index = pool_index(pools)
|
50
52
|
weighted_pools = {}
|
51
53
|
template_backends.each do |t|
|
52
54
|
next unless pool_index.key? t
|
55
|
+
|
53
56
|
index = pool_index[t]
|
54
57
|
clone_target = pools[index]['clone_target'] || config['clone_target']
|
55
58
|
next unless config.key?('backend_weight')
|
59
|
+
|
56
60
|
weight = config['backend_weight'][clone_target]
|
57
61
|
if weight
|
58
62
|
weighted_pools[t] = weight
|
@@ -75,11 +79,17 @@ module Vmpooler
|
|
75
79
|
template_backends.each do |template_backend|
|
76
80
|
vms = backend.smembers("vmpooler__ready__#{template_backend}")
|
77
81
|
next if vms.empty?
|
82
|
+
|
78
83
|
vms.reverse.each do |vm|
|
79
84
|
ready = vm_ready?(vm, config['domain'])
|
80
85
|
if ready
|
81
|
-
backend.smove("vmpooler__ready__#{template_backend}", "vmpooler__running__#{template_backend}", vm)
|
82
|
-
|
86
|
+
smoved = backend.smove("vmpooler__ready__#{template_backend}", "vmpooler__running__#{template_backend}", vm)
|
87
|
+
if smoved
|
88
|
+
return [vm, template_backend, template]
|
89
|
+
else
|
90
|
+
metrics.increment("checkout.smove.failed.#{template_backend}")
|
91
|
+
return [nil, nil, nil]
|
92
|
+
end
|
83
93
|
else
|
84
94
|
backend.smove("vmpooler__ready__#{template_backend}", "vmpooler__completed__#{template_backend}", vm)
|
85
95
|
metrics.increment("checkout.nonresponsive.#{template_backend}")
|
@@ -104,7 +114,7 @@ module Vmpooler
|
|
104
114
|
|
105
115
|
backend.hset('vmpooler__vm__' + vm, 'token:token', request.env['HTTP_X_AUTH_TOKEN'])
|
106
116
|
backend.hset('vmpooler__vm__' + vm, 'token:user',
|
107
|
-
|
117
|
+
backend.hget('vmpooler__token__' + request.env['HTTP_X_AUTH_TOKEN'], 'user')
|
108
118
|
)
|
109
119
|
|
110
120
|
if config['vm_lifetime_auth'].to_i > 0
|
@@ -136,14 +146,14 @@ module Vmpooler
|
|
136
146
|
metrics.increment('checkout.empty.' + requested)
|
137
147
|
break
|
138
148
|
else
|
139
|
-
vms << [
|
149
|
+
vms << [vmpool, vmname, vmtemplate]
|
140
150
|
metrics.increment('checkout.success.' + vmtemplate)
|
141
151
|
end
|
142
152
|
end
|
143
153
|
end
|
144
154
|
|
145
155
|
if failed
|
146
|
-
vms.each do |(vmpool, vmname,
|
156
|
+
vms.each do |(vmpool, vmname, _vmtemplate)|
|
147
157
|
return_vm_to_ready_state(vmpool, vmname)
|
148
158
|
end
|
149
159
|
status 503
|
@@ -203,7 +213,7 @@ module Vmpooler
|
|
203
213
|
def reset_pool(payload)
|
204
214
|
result = { 'ok' => false }
|
205
215
|
|
206
|
-
payload.each do |poolname,
|
216
|
+
payload.each do |poolname, _count|
|
207
217
|
backend.sadd('vmpooler__poolreset', poolname)
|
208
218
|
end
|
209
219
|
status 201
|
@@ -220,7 +230,7 @@ module Vmpooler
|
|
220
230
|
|
221
231
|
payload.each do |poolname, clone_target|
|
222
232
|
unless pools[pool_index[poolname]]['clone_target'] == clone_target
|
223
|
-
pools[pool_index[poolname]]['clone_target']
|
233
|
+
pools[pool_index[poolname]]['clone_target'] = clone_target
|
224
234
|
backend.hset('vmpooler__config__clone_target', poolname, clone_target)
|
225
235
|
pools_updated += 1
|
226
236
|
status 201
|
@@ -234,42 +244,36 @@ module Vmpooler
|
|
234
244
|
def sync_pool_templates
|
235
245
|
pool_index = pool_index(pools)
|
236
246
|
template_configs = backend.hgetall('vmpooler__config__template')
|
237
|
-
|
238
|
-
template_configs.each do |poolname, template|
|
247
|
+
template_configs&.each do |poolname, template|
|
239
248
|
if pool_index.include? poolname
|
240
249
|
unless pools[pool_index[poolname]]['template'] == template
|
241
250
|
pools[pool_index[poolname]]['template'] = template
|
242
251
|
end
|
243
252
|
end
|
244
|
-
end
|
245
253
|
end
|
246
254
|
end
|
247
255
|
|
248
256
|
def sync_pool_sizes
|
249
257
|
pool_index = pool_index(pools)
|
250
258
|
poolsize_configs = backend.hgetall('vmpooler__config__poolsize')
|
251
|
-
|
252
|
-
poolsize_configs.each do |poolname, size|
|
259
|
+
poolsize_configs&.each do |poolname, size|
|
253
260
|
if pool_index.include? poolname
|
254
261
|
unless pools[pool_index[poolname]]['size'] == size.to_i
|
255
262
|
pools[pool_index[poolname]]['size'] == size.to_i
|
256
263
|
end
|
257
264
|
end
|
258
|
-
end
|
259
265
|
end
|
260
266
|
end
|
261
267
|
|
262
268
|
def sync_clone_targets
|
263
269
|
pool_index = pool_index(pools)
|
264
270
|
clone_target_configs = backend.hgetall('vmpooler__config__clone_target')
|
265
|
-
|
266
|
-
clone_target_configs.each do |poolname, clone_target|
|
271
|
+
clone_target_configs&.each do |poolname, clone_target|
|
267
272
|
if pool_index.include? poolname
|
268
273
|
unless pools[pool_index[poolname]]['clone_target'] == clone_target
|
269
274
|
pools[pool_index[poolname]]['clone_target'] == clone_target
|
270
|
-
|
275
|
+
end
|
271
276
|
end
|
272
|
-
end
|
273
277
|
end
|
274
278
|
end
|
275
279
|
|
@@ -368,36 +372,38 @@ module Vmpooler
|
|
368
372
|
pending_hash = get_list_across_pools_redis_scard(pools, 'vmpooler__pending__', backend)
|
369
373
|
lastBoot_hash = get_list_across_pools_redis_hget(pools, 'vmpooler__lastboot', backend)
|
370
374
|
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
375
|
+
unless views and not views.include?("pools")
|
376
|
+
pools.each do |pool|
|
377
|
+
# REMIND: move this out of the API and into the back-end
|
378
|
+
ready = ready_hash[pool['name']]
|
379
|
+
running = running_hash[pool['name']]
|
380
|
+
pending = pending_hash[pool['name']]
|
381
|
+
max = pool['size']
|
382
|
+
lastBoot = lastBoot_hash[pool['name']]
|
383
|
+
aka = pool['alias']
|
384
|
+
|
385
|
+
result[:pools][pool['name']] = {
|
386
|
+
ready: ready,
|
387
|
+
running: running,
|
388
|
+
pending: pending,
|
389
|
+
max: max,
|
390
|
+
lastBoot: lastBoot
|
391
|
+
}
|
387
392
|
|
388
|
-
|
389
|
-
|
390
|
-
|
393
|
+
if aka
|
394
|
+
result[:pools][pool['name']][:alias] = aka
|
395
|
+
end
|
391
396
|
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
397
|
+
# for backwards compatibility, include separate "empty" stats in "status" block
|
398
|
+
if ready == 0
|
399
|
+
result[:status][:empty] ||= []
|
400
|
+
result[:status][:empty].push(pool['name'])
|
396
401
|
|
397
|
-
|
398
|
-
|
402
|
+
result[:status][:ok] = false
|
403
|
+
result[:status][:message] = "Found #{result[:status][:empty].length} empty pools."
|
404
|
+
end
|
399
405
|
end
|
400
|
-
end
|
406
|
+
end
|
401
407
|
|
402
408
|
result[:status][:uptime] = (Time.now - Vmpooler::API.settings.config[:uptime]).round(1) if Vmpooler::API.settings.config[:uptime]
|
403
409
|
|
@@ -442,7 +448,6 @@ module Vmpooler
|
|
442
448
|
if aka
|
443
449
|
result[:pools][pool['name']][:alias] = aka
|
444
450
|
end
|
445
|
-
|
446
451
|
end
|
447
452
|
|
448
453
|
ready_hash = get_list_across_pools_redis_scard(poolscopy, 'vmpooler__ready__', backend)
|
@@ -456,7 +461,7 @@ module Vmpooler
|
|
456
461
|
get "#{api_prefix}/totalrunning/?" do
|
457
462
|
content_type :json
|
458
463
|
queue = {
|
459
|
-
running:
|
464
|
+
running: 0
|
460
465
|
}
|
461
466
|
|
462
467
|
queue[:running] = get_total_across_pools_redis_scard(pools, 'vmpooler__running__', backend)
|
@@ -753,7 +758,7 @@ module Vmpooler
|
|
753
758
|
|
754
759
|
def invalid_pool(payload)
|
755
760
|
invalid = []
|
756
|
-
payload.each do |pool,
|
761
|
+
payload.each do |pool, _clone_target|
|
757
762
|
invalid << pool unless pool_exists?(pool)
|
758
763
|
end
|
759
764
|
invalid
|
@@ -837,7 +842,7 @@ module Vmpooler
|
|
837
842
|
# Look up IP address of the hostname
|
838
843
|
begin
|
839
844
|
ipAddress = TCPSocket.gethostbyname(params[:hostname])[3]
|
840
|
-
rescue
|
845
|
+
rescue StandardError
|
841
846
|
ipAddress = ""
|
842
847
|
end
|
843
848
|
|
@@ -874,6 +879,8 @@ module Vmpooler
|
|
874
879
|
|
875
880
|
status 200
|
876
881
|
result['ok'] = true
|
882
|
+
else
|
883
|
+
metrics.increment('delete.srem.failed')
|
877
884
|
end
|
878
885
|
end
|
879
886
|
|
@@ -893,7 +900,7 @@ module Vmpooler
|
|
893
900
|
if backend.exists('vmpooler__vm__' + params[:hostname])
|
894
901
|
begin
|
895
902
|
jdata = JSON.parse(request.body.read)
|
896
|
-
rescue
|
903
|
+
rescue StandardError
|
897
904
|
halt 400, JSON.pretty_generate(result)
|
898
905
|
end
|
899
906
|
|
@@ -909,13 +916,6 @@ module Vmpooler
|
|
909
916
|
max_lifetime_upper_limit = max_lifetime_upper_limit.to_i
|
910
917
|
if arg.to_i >= max_lifetime_upper_limit
|
911
918
|
failure.push("You provided a lifetime (#{arg}) that exceeds the configured maximum of #{max_lifetime_upper_limit}.")
|
912
|
-
else
|
913
|
-
# also make sure we do not extend past max_lifetime_upper_limit
|
914
|
-
rdata = backend.hgetall('vmpooler__vm__' + params[:hostname])
|
915
|
-
running = ((Time.now - Time.parse(rdata['checkout'])) / 60 / 60).round(2)
|
916
|
-
unless running + arg.to_i < max_lifetime_upper_limit
|
917
|
-
failure.push("You provided a lifetime (#{arg}) that will extend the current lifetime past the configured maximum of #{max_lifetime_upper_limit}.")
|
918
|
-
end
|
919
919
|
end
|
920
920
|
end
|
921
921
|
|
@@ -936,7 +936,7 @@ module Vmpooler
|
|
936
936
|
end
|
937
937
|
end
|
938
938
|
|
939
|
-
if failure.
|
939
|
+
if !failure.empty?
|
940
940
|
status 400
|
941
941
|
result['failure'] = failure
|
942
942
|
else
|