vmpooler 0.18.0 → 1.1.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/lib/vmpooler.rb +9 -14
- data/lib/vmpooler/api/dashboard.rb +18 -20
- data/lib/vmpooler/api/helpers.rb +11 -13
- data/lib/vmpooler/api/v1.rb +93 -52
- data/lib/vmpooler/metrics/dummy_statsd.rb +0 -3
- data/lib/vmpooler/metrics/graphite.rb +2 -0
- data/lib/vmpooler/metrics/promstats.rb +17 -15
- data/lib/vmpooler/metrics/promstats/collector_middleware.rb +1 -1
- data/lib/vmpooler/metrics/statsd.rb +5 -3
- data/lib/vmpooler/pool_manager.rb +48 -98
- data/lib/vmpooler/providers/dummy.rb +20 -38
- data/lib/vmpooler/providers/vsphere.rb +18 -27
- data/lib/vmpooler/version.rb +1 -1
- metadata +38 -46
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9f802530711b24fac0c8b34198895a2b4b5d18f32942bc4fb7b35d5756ead742
|
4
|
+
data.tar.gz: 31df1542e5d1c2441976780c10c523f95617a8d0ea57457e6c8afd3a488ef983
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 40705e369c0b5dcc9b5f8a9d1f30258586f6df66528421b054fb772d2a51a5bcbcb3795f23efa1239e9948322b807406cffef2107f741d5c1d713a0f0c125592
|
7
|
+
data.tar.gz: ef3eb7549072874d71c9ddb0e50913679f47006cdecff869a0db49e7cc8e7af00d4f4455a824e441fb93ef94999b81e411d06418ec5ce08481c9318b670a55aa
|
data/lib/vmpooler.rb
CHANGED
@@ -16,7 +16,6 @@ module Vmpooler
|
|
16
16
|
require 'yaml'
|
17
17
|
|
18
18
|
# Dependencies for tracing
|
19
|
-
require 'opentelemetry-api'
|
20
19
|
require 'opentelemetry-instrumentation-concurrent_ruby'
|
21
20
|
require 'opentelemetry-instrumentation-redis'
|
22
21
|
require 'opentelemetry-instrumentation-sinatra'
|
@@ -53,17 +52,13 @@ module Vmpooler
|
|
53
52
|
|
54
53
|
# Bail out if someone attempts to start vmpooler with dummy authentication
|
55
54
|
# without enbaling debug mode.
|
56
|
-
if parsed_config.key? :auth
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
raise warning.join(";\s")
|
65
|
-
end
|
66
|
-
end
|
55
|
+
if parsed_config.key?(:auth) && parsed_config[:auth]['provider'] == 'dummy' && !ENV['VMPOOLER_DEBUG']
|
56
|
+
warning = [
|
57
|
+
'Dummy authentication should not be used outside of debug mode',
|
58
|
+
'please set environment variable VMPOOLER_DEBUG to \'true\' if you want to use dummy authentication'
|
59
|
+
]
|
60
|
+
|
61
|
+
raise warning.join(";\s")
|
67
62
|
end
|
68
63
|
|
69
64
|
# Set some configuration defaults
|
@@ -140,14 +135,14 @@ module Vmpooler
|
|
140
135
|
parsed_config[:pool_names] << pool['name']
|
141
136
|
pool['ready_ttl'] ||= parsed_config[:config]['ready_ttl']
|
142
137
|
if pool['alias']
|
143
|
-
if pool['alias'].
|
138
|
+
if pool['alias'].instance_of?(Array)
|
144
139
|
pool['alias'].each do |pool_alias|
|
145
140
|
parsed_config[:alias] ||= {}
|
146
141
|
parsed_config[:alias][pool_alias] = [pool['name']] unless parsed_config[:alias].key? pool_alias
|
147
142
|
parsed_config[:alias][pool_alias] << pool['name'] unless parsed_config[:alias][pool_alias].include? pool['name']
|
148
143
|
parsed_config[:pool_names] << pool_alias
|
149
144
|
end
|
150
|
-
elsif pool['alias'].
|
145
|
+
elsif pool['alias'].instance_of?(String)
|
151
146
|
parsed_config[:alias][pool['alias']] = pool['name']
|
152
147
|
parsed_config[:pool_names] << pool['alias']
|
153
148
|
end
|
@@ -128,34 +128,32 @@ module Vmpooler
|
|
128
128
|
|
129
129
|
pools.each do |pool|
|
130
130
|
running = running_hash[pool['name']]
|
131
|
-
pool['major'] = Regexp.last_match[1] if pool['name'] =~ /^(\w+)
|
131
|
+
pool['major'] = Regexp.last_match[1] if pool['name'] =~ /^(\w+)-/
|
132
132
|
result[pool['major']] ||= {}
|
133
133
|
result[pool['major']]['running'] = result[pool['major']]['running'].to_i + running.to_i
|
134
134
|
end
|
135
135
|
|
136
|
-
if params[:history]
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
result[pool['major']]['history'][i] = result[pool['major']]['history'][i].to_i + pool['last'].to_i
|
153
|
-
end
|
136
|
+
if params[:history] && graph_url
|
137
|
+
begin
|
138
|
+
buffer = URI.parse(graph_link('.running.*&from=-1hour&format=json')).read
|
139
|
+
JSON.parse(buffer).each do |pool|
|
140
|
+
if pool['target'] =~ /.*\.(.*)$/
|
141
|
+
pool['name'] = Regexp.last_match[1]
|
142
|
+
pool['major'] = Regexp.last_match[1] if pool['name'] =~ /^(\w+)-/
|
143
|
+
result[pool['major']]['history'] ||= []
|
144
|
+
|
145
|
+
for i in 0..pool['datapoints'].length
|
146
|
+
if pool['datapoints'][i] && pool['datapoints'][i][0]
|
147
|
+
pool['last'] = pool['datapoints'][i][0]
|
148
|
+
result[pool['major']]['history'][i] ||= 0
|
149
|
+
result[pool['major']]['history'][i] = result[pool['major']]['history'][i].to_i + pool['datapoints'][i][0].to_i
|
150
|
+
else
|
151
|
+
result[pool['major']]['history'][i] = result[pool['major']]['history'][i].to_i + pool['last'].to_i
|
154
152
|
end
|
155
153
|
end
|
156
154
|
end
|
157
|
-
rescue StandardError
|
158
155
|
end
|
156
|
+
rescue StandardError
|
159
157
|
end
|
160
158
|
end
|
161
159
|
JSON.pretty_generate(result)
|
data/lib/vmpooler/api/helpers.rb
CHANGED
@@ -13,12 +13,12 @@ module Vmpooler
|
|
13
13
|
def valid_token?(backend)
|
14
14
|
return false unless has_token?
|
15
15
|
|
16
|
-
backend.exists?(
|
16
|
+
backend.exists?("vmpooler__token__#{request.env['HTTP_X_AUTH_TOKEN']}") ? true : false
|
17
17
|
end
|
18
18
|
|
19
19
|
def validate_token(backend)
|
20
20
|
if valid_token?(backend)
|
21
|
-
backend.hset(
|
21
|
+
backend.hset("vmpooler__token__#{request.env['HTTP_X_AUTH_TOKEN']}", 'last', Time.now)
|
22
22
|
|
23
23
|
return true
|
24
24
|
end
|
@@ -118,8 +118,8 @@ module Vmpooler
|
|
118
118
|
tags.each_pair do |tag, value|
|
119
119
|
next if value.nil? or value.empty?
|
120
120
|
|
121
|
-
backend.hset(
|
122
|
-
backend.hset(
|
121
|
+
backend.hset("vmpooler__vm__#{hostname}", "tag:#{tag}", value)
|
122
|
+
backend.hset("vmpooler__tag__#{Date.today}", "#{hostname}:#{tag}", value)
|
123
123
|
end
|
124
124
|
end
|
125
125
|
end
|
@@ -147,7 +147,7 @@ module Vmpooler
|
|
147
147
|
|
148
148
|
def hostname_shorten(hostname, domain=nil)
|
149
149
|
if domain && hostname =~ /^[\w-]+\.#{domain}$/
|
150
|
-
hostname = hostname[/[
|
150
|
+
hostname = hostname[/[^.]+/]
|
151
151
|
end
|
152
152
|
|
153
153
|
hostname
|
@@ -253,17 +253,15 @@ module Vmpooler
|
|
253
253
|
|
254
254
|
tags = {}
|
255
255
|
|
256
|
-
backend.hgetall(
|
256
|
+
backend.hgetall("vmpooler__tag__#{date_str}").each do |key, value|
|
257
257
|
hostname = 'unknown'
|
258
258
|
tag = 'unknown'
|
259
259
|
|
260
|
-
if key =~
|
260
|
+
if key =~ /:/
|
261
261
|
hostname, tag = key.split(':', 2)
|
262
262
|
end
|
263
263
|
|
264
|
-
if opts[:only]
|
265
|
-
next unless tag == opts[:only]
|
266
|
-
end
|
264
|
+
next if opts[:only] && tag != opts[:only]
|
267
265
|
|
268
266
|
tags[tag] ||= {}
|
269
267
|
tags[tag][value] ||= 0
|
@@ -321,7 +319,7 @@ module Vmpooler
|
|
321
319
|
}
|
322
320
|
}
|
323
321
|
|
324
|
-
task[:count][:total] = backend.hlen(
|
322
|
+
task[:count][:total] = backend.hlen("vmpooler__#{task_str}__#{date_str}").to_i
|
325
323
|
|
326
324
|
if task[:count][:total] > 0
|
327
325
|
if opts[:bypool] == true
|
@@ -330,11 +328,11 @@ module Vmpooler
|
|
330
328
|
task[:count][:pool] = {}
|
331
329
|
task[:duration][:pool] = {}
|
332
330
|
|
333
|
-
backend.hgetall(
|
331
|
+
backend.hgetall("vmpooler__#{task_str}__#{date_str}").each do |key, value|
|
334
332
|
pool = 'unknown'
|
335
333
|
hostname = 'unknown'
|
336
334
|
|
337
|
-
if key =~
|
335
|
+
if key =~ /:/
|
338
336
|
pool, hostname = key.split(':')
|
339
337
|
else
|
340
338
|
hostname = key
|
data/lib/vmpooler/api/v1.rb
CHANGED
@@ -163,24 +163,25 @@ module Vmpooler
|
|
163
163
|
end
|
164
164
|
|
165
165
|
def return_vm_to_ready_state(template, vm)
|
166
|
+
backend.srem("vmpooler__migrating__#{template}", vm)
|
167
|
+
backend.hdel("vmpooler__active__#{template}", vm)
|
168
|
+
backend.hdel("vmpooler__vm__#{vm}", 'checkout', 'token:token', 'token:user')
|
166
169
|
backend.smove("vmpooler__running__#{template}", "vmpooler__ready__#{template}", vm)
|
167
170
|
end
|
168
171
|
|
169
172
|
def account_for_starting_vm(template, vm)
|
173
|
+
user = backend.hget("vmpooler__token__#{request.env['HTTP_X_AUTH_TOKEN']}", 'user')
|
174
|
+
has_token_result = has_token?
|
170
175
|
backend.sadd("vmpooler__migrating__#{template}", vm)
|
171
176
|
backend.hset("vmpooler__active__#{template}", vm, Time.now)
|
172
177
|
backend.hset("vmpooler__vm__#{vm}", 'checkout', Time.now)
|
173
178
|
|
174
|
-
if Vmpooler::API.settings.config[:auth] and
|
175
|
-
|
176
|
-
|
177
|
-
backend.hset('vmpooler__vm__' + vm, 'token:token', request.env['HTTP_X_AUTH_TOKEN'])
|
178
|
-
backend.hset('vmpooler__vm__' + vm, 'token:user',
|
179
|
-
backend.hget('vmpooler__token__' + request.env['HTTP_X_AUTH_TOKEN'], 'user')
|
180
|
-
)
|
179
|
+
if Vmpooler::API.settings.config[:auth] and has_token_result
|
180
|
+
backend.hset("vmpooler__vm__#{vm}", 'token:token', request.env['HTTP_X_AUTH_TOKEN'])
|
181
|
+
backend.hset("vmpooler__vm__#{vm}", 'token:user', user)
|
181
182
|
|
182
183
|
if config['vm_lifetime_auth'].to_i > 0
|
183
|
-
backend.hset(
|
184
|
+
backend.hset("vmpooler__vm__#{vm}", 'lifetime', config['vm_lifetime_auth'].to_i)
|
184
185
|
end
|
185
186
|
end
|
186
187
|
end
|
@@ -200,16 +201,20 @@ module Vmpooler
|
|
200
201
|
failed = false
|
201
202
|
vms = []
|
202
203
|
|
204
|
+
validate_token(backend) if Vmpooler::API.settings.config[:auth] and has_token?
|
205
|
+
|
203
206
|
payload.each do |requested, count|
|
204
207
|
count.to_i.times do |_i|
|
205
208
|
vmname, vmpool, vmtemplate = fetch_single_vm(requested)
|
206
|
-
if
|
209
|
+
if vmname
|
210
|
+
account_for_starting_vm(vmpool, vmname)
|
211
|
+
vms << [vmpool, vmname, vmtemplate]
|
212
|
+
metrics.increment("checkout.success.#{vmpool}")
|
213
|
+
update_user_metrics('allocate', vmname) if Vmpooler::API.settings.config[:config]['usage_stats']
|
214
|
+
else
|
207
215
|
failed = true
|
208
|
-
metrics.increment(
|
216
|
+
metrics.increment("checkout.empty.#{requested}")
|
209
217
|
break
|
210
|
-
else
|
211
|
-
vms << [vmpool, vmname, vmtemplate]
|
212
|
-
metrics.increment('checkout.success.' + vmtemplate)
|
213
218
|
end
|
214
219
|
end
|
215
220
|
end
|
@@ -220,8 +225,7 @@ module Vmpooler
|
|
220
225
|
end
|
221
226
|
status 503
|
222
227
|
else
|
223
|
-
vms.each do |(
|
224
|
-
account_for_starting_vm(vmpool, vmname)
|
228
|
+
vms.each do |(_vmpool, vmname, vmtemplate)|
|
225
229
|
update_result_hosts(result, vmtemplate, vmname)
|
226
230
|
end
|
227
231
|
|
@@ -232,6 +236,46 @@ module Vmpooler
|
|
232
236
|
result
|
233
237
|
end
|
234
238
|
|
239
|
+
def update_user_metrics(operation, vmname)
|
240
|
+
backend.multi
|
241
|
+
backend.hget("vmpooler__vm__#{vmname}", 'tag:jenkins_build_url')
|
242
|
+
backend.hget("vmpooler__vm__#{vmname}", 'token:user')
|
243
|
+
backend.hget("vmpooler__vm__#{vmname}", 'template')
|
244
|
+
jenkins_build_url, user, poolname = backend.exec
|
245
|
+
|
246
|
+
if user
|
247
|
+
user = user.gsub('.', '_')
|
248
|
+
else
|
249
|
+
user = 'unauthenticated'
|
250
|
+
end
|
251
|
+
metrics.increment("user.#{user}.#{operation}.#{poolname}")
|
252
|
+
|
253
|
+
if jenkins_build_url
|
254
|
+
if jenkins_build_url.include? 'litmus'
|
255
|
+
# Very simple filter for Litmus jobs - just count them coming through for the moment.
|
256
|
+
metrics.increment("usage_litmus.#{user}.#{operation}.#{poolname}")
|
257
|
+
return
|
258
|
+
end
|
259
|
+
|
260
|
+
url_parts = jenkins_build_url.split('/')[2..-1]
|
261
|
+
jenkins_instance = url_parts[0].gsub('.', '_')
|
262
|
+
value_stream_parts = url_parts[2].split('_')
|
263
|
+
value_stream_parts = value_stream_parts.map { |s| s.gsub('.', '_') }
|
264
|
+
value_stream = value_stream_parts.shift
|
265
|
+
branch = value_stream_parts.pop
|
266
|
+
project = value_stream_parts.shift
|
267
|
+
job_name = value_stream_parts.join('_')
|
268
|
+
build_metadata_parts = url_parts[3]
|
269
|
+
component_to_test = component_to_test('RMM_COMPONENT_TO_TEST_NAME', build_metadata_parts)
|
270
|
+
|
271
|
+
metrics.increment("usage_jenkins_instance.#{jenkins_instance}.#{value_stream}.#{operation}.#{poolname}")
|
272
|
+
metrics.increment("usage_branch_project.#{branch}.#{project}.#{operation}.#{poolname}")
|
273
|
+
metrics.increment("usage_job_component.#{job_name}.#{component_to_test}.#{operation}.#{poolname}")
|
274
|
+
end
|
275
|
+
rescue StandardError => e
|
276
|
+
puts 'd', "[!] [#{poolname}] failed while evaluating usage labels on '#{vmname}' with an error: #{e}"
|
277
|
+
end
|
278
|
+
|
235
279
|
def update_pool_size(payload)
|
236
280
|
result = { 'ok' => false }
|
237
281
|
|
@@ -337,7 +381,7 @@ module Vmpooler
|
|
337
381
|
payload&.each do |poolname, count|
|
338
382
|
next unless count.to_i > config['max_ondemand_instances_per_request']
|
339
383
|
|
340
|
-
metrics.increment(
|
384
|
+
metrics.increment("ondemandrequest_fail.toomanyrequests.#{poolname}")
|
341
385
|
return true
|
342
386
|
end
|
343
387
|
false
|
@@ -380,7 +424,7 @@ module Vmpooler
|
|
380
424
|
if Vmpooler::API.settings.config[:auth] and has_token?
|
381
425
|
backend.hset("vmpooler__odrequest__#{request_id}", 'token:token', request.env['HTTP_X_AUTH_TOKEN'])
|
382
426
|
backend.hset("vmpooler__odrequest__#{request_id}", 'token:user',
|
383
|
-
backend.hget(
|
427
|
+
backend.hget("vmpooler__token__#{request.env['HTTP_X_AUTH_TOKEN']}", 'user'))
|
384
428
|
end
|
385
429
|
|
386
430
|
result['domain'] = config['domain'] if config['domain']
|
@@ -542,9 +586,9 @@ module Vmpooler
|
|
542
586
|
if subpool.include?(p['name'])
|
543
587
|
true
|
544
588
|
elsif !p['alias'].nil?
|
545
|
-
if p['alias'].
|
589
|
+
if p['alias'].instance_of?(Array)
|
546
590
|
(p['alias'] & subpool).any?
|
547
|
-
elsif p['alias'].
|
591
|
+
elsif p['alias'].instance_of?(String)
|
548
592
|
subpool.include?(p['alias'])
|
549
593
|
end
|
550
594
|
end
|
@@ -727,14 +771,14 @@ module Vmpooler
|
|
727
771
|
result = { 'ok' => false }
|
728
772
|
|
729
773
|
if Vmpooler::API.settings.config[:auth]
|
730
|
-
token = backend.hgetall(
|
774
|
+
token = backend.hgetall("vmpooler__token__#{params[:token]}")
|
731
775
|
|
732
776
|
if not token.nil? and not token.empty?
|
733
777
|
status 200
|
734
778
|
|
735
779
|
pools.each do |pool|
|
736
|
-
backend.smembers(
|
737
|
-
if backend.hget(
|
780
|
+
backend.smembers("vmpooler__running__#{pool['name']}").each do |vm|
|
781
|
+
if backend.hget("vmpooler__vm__#{vm}", 'token:token') == params[:token]
|
738
782
|
token['vms'] ||= {}
|
739
783
|
token['vms']['running'] ||= []
|
740
784
|
token['vms']['running'].push(vm)
|
@@ -760,7 +804,7 @@ module Vmpooler
|
|
760
804
|
|
761
805
|
need_auth!
|
762
806
|
|
763
|
-
if backend.del(
|
807
|
+
if backend.del("vmpooler__token__#{params[:token]}").to_i > 0
|
764
808
|
status 200
|
765
809
|
result['ok'] = true
|
766
810
|
end
|
@@ -783,8 +827,8 @@ module Vmpooler
|
|
783
827
|
o = [('a'..'z'), ('0'..'9')].map(&:to_a).flatten
|
784
828
|
result['token'] = o[rand(25)] + (0...31).map { o[rand(o.length)] }.join
|
785
829
|
|
786
|
-
backend.hset(
|
787
|
-
backend.hset(
|
830
|
+
backend.hset("vmpooler__token__#{result['token']}", 'user', @auth.username)
|
831
|
+
backend.hset("vmpooler__token__#{result['token']}", 'created', Time.now)
|
788
832
|
|
789
833
|
status 200
|
790
834
|
result['ok'] = true
|
@@ -823,7 +867,7 @@ module Vmpooler
|
|
823
867
|
else
|
824
868
|
result[:bad_templates] = invalid
|
825
869
|
invalid.each do |bad_template|
|
826
|
-
metrics.increment(
|
870
|
+
metrics.increment("ondemandrequest_fail.invalid.#{bad_template}")
|
827
871
|
end
|
828
872
|
status 404
|
829
873
|
end
|
@@ -858,7 +902,7 @@ module Vmpooler
|
|
858
902
|
else
|
859
903
|
result[:bad_templates] = invalid
|
860
904
|
invalid.each do |bad_template|
|
861
|
-
metrics.increment(
|
905
|
+
metrics.increment("ondemandrequest_fail.invalid.#{bad_template}")
|
862
906
|
end
|
863
907
|
status 404
|
864
908
|
end
|
@@ -904,7 +948,7 @@ module Vmpooler
|
|
904
948
|
result = atomically_allocate_vms(payload)
|
905
949
|
else
|
906
950
|
invalid.each do |bad_template|
|
907
|
-
metrics.increment(
|
951
|
+
metrics.increment("checkout.invalid.#{bad_template}")
|
908
952
|
end
|
909
953
|
status 404
|
910
954
|
end
|
@@ -980,7 +1024,8 @@ module Vmpooler
|
|
980
1024
|
result['ok'] = true
|
981
1025
|
status 202
|
982
1026
|
|
983
|
-
|
1027
|
+
case request_hash['status']
|
1028
|
+
when 'ready'
|
984
1029
|
result['ready'] = true
|
985
1030
|
Parsing.get_platform_pool_count(request_hash['requested']) do |platform_alias, pool, _count|
|
986
1031
|
instances = backend.smembers("vmpooler__#{request_id}__#{platform_alias}__#{pool}")
|
@@ -993,10 +1038,10 @@ module Vmpooler
|
|
993
1038
|
end
|
994
1039
|
result['domain'] = config['domain'] if config['domain']
|
995
1040
|
status 200
|
996
|
-
|
1041
|
+
when 'failed'
|
997
1042
|
result['message'] = "The request failed to provision instances within the configured ondemand_request_ttl '#{config['ondemand_request_ttl']}'"
|
998
1043
|
status 200
|
999
|
-
|
1044
|
+
when 'deleted'
|
1000
1045
|
result['message'] = 'The request has been deleted'
|
1001
1046
|
status 200
|
1002
1047
|
else
|
@@ -1059,7 +1104,7 @@ module Vmpooler
|
|
1059
1104
|
result = atomically_allocate_vms(payload)
|
1060
1105
|
else
|
1061
1106
|
invalid.each do |bad_template|
|
1062
|
-
metrics.increment(
|
1107
|
+
metrics.increment("checkout.invalid.#{bad_template}")
|
1063
1108
|
end
|
1064
1109
|
status 404
|
1065
1110
|
end
|
@@ -1082,7 +1127,7 @@ module Vmpooler
|
|
1082
1127
|
|
1083
1128
|
params[:hostname] = hostname_shorten(params[:hostname], config['domain'])
|
1084
1129
|
|
1085
|
-
rdata = backend.hgetall(
|
1130
|
+
rdata = backend.hgetall("vmpooler__vm__#{params[:hostname]}")
|
1086
1131
|
unless rdata.empty?
|
1087
1132
|
status 200
|
1088
1133
|
result['ok'] = true
|
@@ -1093,7 +1138,7 @@ module Vmpooler
|
|
1093
1138
|
result[params[:hostname]]['lifetime'] = (rdata['lifetime'] || config['vm_lifetime']).to_i
|
1094
1139
|
|
1095
1140
|
if rdata['destroy']
|
1096
|
-
result[params[:hostname]]['running'] = ((Time.parse(rdata['destroy']) - Time.parse(rdata['checkout'])) / 60 / 60).round(2)
|
1141
|
+
result[params[:hostname]]['running'] = ((Time.parse(rdata['destroy']) - Time.parse(rdata['checkout'])) / 60 / 60).round(2) if rdata['checkout']
|
1097
1142
|
result[params[:hostname]]['state'] = 'destroyed'
|
1098
1143
|
elsif rdata['checkout']
|
1099
1144
|
result[params[:hostname]]['running'] = ((Time.now - Time.parse(rdata['checkout'])) / 60 / 60).round(2)
|
@@ -1155,16 +1200,17 @@ module Vmpooler
|
|
1155
1200
|
|
1156
1201
|
params[:hostname] = hostname_shorten(params[:hostname], config['domain'])
|
1157
1202
|
|
1158
|
-
rdata = backend.hgetall(
|
1203
|
+
rdata = backend.hgetall("vmpooler__vm__#{params[:hostname]}")
|
1159
1204
|
unless rdata.empty?
|
1160
1205
|
need_token! if rdata['token:token']
|
1161
1206
|
|
1162
|
-
if backend.srem(
|
1163
|
-
backend.sadd(
|
1207
|
+
if backend.srem("vmpooler__running__#{rdata['template']}", params[:hostname])
|
1208
|
+
backend.sadd("vmpooler__completed__#{rdata['template']}", params[:hostname])
|
1164
1209
|
|
1165
1210
|
status 200
|
1166
1211
|
result['ok'] = true
|
1167
1212
|
metrics.increment('delete.success')
|
1213
|
+
update_user_metrics('destroy', params[:hostname]) if Vmpooler::API.settings.config[:config]['usage_stats']
|
1168
1214
|
else
|
1169
1215
|
metrics.increment('delete.failed')
|
1170
1216
|
end
|
@@ -1184,7 +1230,7 @@ module Vmpooler
|
|
1184
1230
|
|
1185
1231
|
params[:hostname] = hostname_shorten(params[:hostname], config['domain'])
|
1186
1232
|
|
1187
|
-
if backend.exists?(
|
1233
|
+
if backend.exists?("vmpooler__vm__#{params[:hostname]}")
|
1188
1234
|
begin
|
1189
1235
|
jdata = JSON.parse(request.body.read)
|
1190
1236
|
rescue StandardError
|
@@ -1212,13 +1258,8 @@ module Vmpooler
|
|
1212
1258
|
end
|
1213
1259
|
|
1214
1260
|
when 'tags'
|
1215
|
-
unless arg.is_a?(Hash)
|
1216
|
-
|
1217
|
-
end
|
1218
|
-
|
1219
|
-
if config['allowed_tags']
|
1220
|
-
failure.push("You provided unsuppored tags (#{arg}).") if not (arg.keys - config['allowed_tags']).empty?
|
1221
|
-
end
|
1261
|
+
failure.push("You provided tags (#{arg}) as something other than a hash.") unless arg.is_a?(Hash)
|
1262
|
+
failure.push("You provided unsuppored tags (#{arg}).") if config['allowed_tags'] && !(arg.keys - config['allowed_tags']).empty?
|
1222
1263
|
else
|
1223
1264
|
failure.push("Unknown argument #{arg}.")
|
1224
1265
|
end
|
@@ -1235,7 +1276,7 @@ module Vmpooler
|
|
1235
1276
|
|
1236
1277
|
arg = arg.to_i
|
1237
1278
|
|
1238
|
-
backend.hset(
|
1279
|
+
backend.hset("vmpooler__vm__#{params[:hostname]}", param, arg)
|
1239
1280
|
when 'tags'
|
1240
1281
|
filter_tags(arg)
|
1241
1282
|
export_tags(backend, params[:hostname], arg)
|
@@ -1261,11 +1302,11 @@ module Vmpooler
|
|
1261
1302
|
|
1262
1303
|
params[:hostname] = hostname_shorten(params[:hostname], config['domain'])
|
1263
1304
|
|
1264
|
-
if ((params[:size].to_i > 0 )and (backend.exists?(
|
1305
|
+
if ((params[:size].to_i > 0 )and (backend.exists?("vmpooler__vm__#{params[:hostname]}")))
|
1265
1306
|
result[params[:hostname]] = {}
|
1266
1307
|
result[params[:hostname]]['disk'] = "+#{params[:size]}gb"
|
1267
1308
|
|
1268
|
-
backend.sadd('vmpooler__tasks__disk', params[:hostname]
|
1309
|
+
backend.sadd('vmpooler__tasks__disk', "#{params[:hostname]}:#{params[:size]}")
|
1269
1310
|
|
1270
1311
|
status 202
|
1271
1312
|
result['ok'] = true
|
@@ -1285,13 +1326,13 @@ module Vmpooler
|
|
1285
1326
|
|
1286
1327
|
params[:hostname] = hostname_shorten(params[:hostname], config['domain'])
|
1287
1328
|
|
1288
|
-
if backend.exists?(
|
1329
|
+
if backend.exists?("vmpooler__vm__#{params[:hostname]}")
|
1289
1330
|
result[params[:hostname]] = {}
|
1290
1331
|
|
1291
1332
|
o = [('a'..'z'), ('0'..'9')].map(&:to_a).flatten
|
1292
1333
|
result[params[:hostname]]['snapshot'] = o[rand(25)] + (0...31).map { o[rand(o.length)] }.join
|
1293
1334
|
|
1294
|
-
backend.sadd('vmpooler__tasks__snapshot', params[:hostname]
|
1335
|
+
backend.sadd('vmpooler__tasks__snapshot', "#{params[:hostname]}:#{result[params[:hostname]]['snapshot']}")
|
1295
1336
|
|
1296
1337
|
status 202
|
1297
1338
|
result['ok'] = true
|
@@ -1311,8 +1352,8 @@ module Vmpooler
|
|
1311
1352
|
|
1312
1353
|
params[:hostname] = hostname_shorten(params[:hostname], config['domain'])
|
1313
1354
|
|
1314
|
-
unless backend.hget(
|
1315
|
-
backend.sadd('vmpooler__tasks__snapshot-revert', params[:hostname]
|
1355
|
+
unless backend.hget("vmpooler__vm__#{params[:hostname]}", "snapshot:#{params[:snapshot]}").to_i.zero?
|
1356
|
+
backend.sadd('vmpooler__tasks__snapshot-revert', "#{params[:hostname]}:#{params[:snapshot]}")
|
1316
1357
|
|
1317
1358
|
status 202
|
1318
1359
|
result['ok'] = true
|