vmfloaty 0.11.0 → 0.11.1
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/vmfloaty.rb +32 -10
- data/lib/vmfloaty/abs.rb +21 -3
- data/lib/vmfloaty/nonstandard_pooler.rb +1 -1
- data/lib/vmfloaty/utils.rb +46 -21
- data/lib/vmfloaty/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5ebdafe4b60af0f238330584cbe7ee1a3a5258b1671b7805d45551c16c69465a
|
4
|
+
data.tar.gz: '002138e04b43f670d76d7f0311dbb4770e2153306874a527f0e537c59dfafc9e'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 23e7ea9dbb546740ea16418f7a5e00d184df44634bf5dc9ff5421907a7fac55ff65d7d74516f1762a805cf865ff941b97e474e20db101029b176b89f1946d662
|
7
|
+
data.tar.gz: 7ffa31b013b4d332a6e19f56b56a6f55560dbc6a65702cf1b81be7317bc1b59b434af674f7f54ddb13f4dc611e96e27c947aa6c4679031f32b3475b49c1e5e40
|
data/lib/vmfloaty.rb
CHANGED
@@ -87,6 +87,7 @@ class Vmfloaty
|
|
87
87
|
c.option '--verbose', 'Enables verbose output'
|
88
88
|
c.option '--service STRING', String, 'Configured pooler service name'
|
89
89
|
c.option '--active', 'Prints information about active vms for a given token'
|
90
|
+
c.option '--json', 'Prints information as JSON'
|
90
91
|
c.option '--token STRING', String, 'Token for pooler service'
|
91
92
|
c.option '--url STRING', String, 'URL of pooler service'
|
92
93
|
c.action do |args, options|
|
@@ -100,10 +101,18 @@ class Vmfloaty
|
|
100
101
|
running_vms = service.list_active(verbose)
|
101
102
|
host = URI.parse(service.url).host
|
102
103
|
if running_vms.empty?
|
103
|
-
|
104
|
+
if options.json
|
105
|
+
puts {}.to_json
|
106
|
+
else
|
107
|
+
FloatyLogger.info "You have no running VMs on #{host}"
|
108
|
+
end
|
104
109
|
else
|
105
|
-
|
106
|
-
|
110
|
+
if options.json
|
111
|
+
puts Utils.get_host_data(verbose, service, running_vms).to_json
|
112
|
+
else
|
113
|
+
puts "Your VMs on #{host}:"
|
114
|
+
Utils.pretty_print_hosts(verbose, service, running_vms)
|
115
|
+
end
|
107
116
|
end
|
108
117
|
else
|
109
118
|
# list available vms from pooler
|
@@ -200,6 +209,7 @@ class Vmfloaty
|
|
200
209
|
c.option '--service STRING', String, 'Configured pooler service name'
|
201
210
|
c.option '--all', 'Deletes all vms acquired by a token'
|
202
211
|
c.option '-f', 'Does not prompt user when deleting all vms'
|
212
|
+
c.option '--json', 'Outputs hosts scheduled for deletion as JSON'
|
203
213
|
c.option '--token STRING', String, 'Token for pooler service'
|
204
214
|
c.option '--url STRING', String, 'URL of pooler service'
|
205
215
|
c.action do |args, options|
|
@@ -215,12 +225,18 @@ class Vmfloaty
|
|
215
225
|
if delete_all
|
216
226
|
running_vms = service.list_active(verbose)
|
217
227
|
if running_vms.empty?
|
218
|
-
|
228
|
+
if options.json
|
229
|
+
puts {}.to_json
|
230
|
+
else
|
231
|
+
FloatyLogger.info "You have no running VMs."
|
232
|
+
end
|
219
233
|
else
|
220
|
-
Utils.pretty_print_hosts(verbose, service, running_vms, true)
|
221
|
-
# Confirm deletion
|
222
234
|
confirmed = true
|
223
|
-
|
235
|
+
unless force
|
236
|
+
Utils.pretty_print_hosts(verbose, service, running_vms, true)
|
237
|
+
# Confirm deletion
|
238
|
+
confirmed = agree('Delete all these VMs? [y/N]')
|
239
|
+
end
|
224
240
|
if confirmed
|
225
241
|
response = service.delete(verbose, running_vms)
|
226
242
|
response.each do |hostname, result|
|
@@ -257,9 +273,15 @@ class Vmfloaty
|
|
257
273
|
|
258
274
|
unless successes.empty?
|
259
275
|
FloatyLogger.info unless failures.empty?
|
260
|
-
|
261
|
-
|
262
|
-
|
276
|
+
if options.json
|
277
|
+
puts successes.to_json
|
278
|
+
else
|
279
|
+
puts 'Scheduled the following VMs for deletion:'
|
280
|
+
output = ''
|
281
|
+
successes.each do |hostname|
|
282
|
+
output += "- #{hostname}\n"
|
283
|
+
end
|
284
|
+
puts output
|
263
285
|
end
|
264
286
|
end
|
265
287
|
|
data/lib/vmfloaty/abs.rb
CHANGED
@@ -229,10 +229,10 @@ class ABS
|
|
229
229
|
|
230
230
|
retries = 360
|
231
231
|
|
232
|
-
|
232
|
+
validate_queue_status_response(res.status, res.body, "Initial request", verbose)
|
233
233
|
|
234
234
|
(1..retries).each do |i|
|
235
|
-
queue_place, res_body = check_queue(conn, saved_job_id, req_obj)
|
235
|
+
queue_place, res_body = check_queue(conn, saved_job_id, req_obj, verbose)
|
236
236
|
return translated(res_body) if res_body
|
237
237
|
|
238
238
|
sleep_seconds = 10 if i >= 10
|
@@ -262,11 +262,12 @@ class ABS
|
|
262
262
|
vmpooler_formatted_body
|
263
263
|
end
|
264
264
|
|
265
|
-
def self.check_queue(conn, job_id, req_obj)
|
265
|
+
def self.check_queue(conn, job_id, req_obj, verbose)
|
266
266
|
queue_info_res = conn.get "status/queue/info/#{job_id}"
|
267
267
|
queue_info = JSON.parse(queue_info_res.body)
|
268
268
|
|
269
269
|
res = conn.post 'request', req_obj.to_json
|
270
|
+
validate_queue_status_response(res.status, res.body, "Check queue request", verbose)
|
270
271
|
|
271
272
|
unless res.body.empty?
|
272
273
|
res_body = JSON.parse(res.body)
|
@@ -315,4 +316,21 @@ class ABS
|
|
315
316
|
def self.revert(_verbose, _url, _hostname, _token, _snapshot_sha)
|
316
317
|
raise NoMethodError, 'revert is not defined for ABS'
|
317
318
|
end
|
319
|
+
|
320
|
+
# Validate the http code returned during a queue status request.
|
321
|
+
#
|
322
|
+
# Return a success message that can be displayed if the status code is
|
323
|
+
# success, otherwise raise an error.
|
324
|
+
def self.validate_queue_status_response(status_code, body, request_name, verbose)
|
325
|
+
case status_code
|
326
|
+
when 200
|
327
|
+
"#{request_name} returned success (Code 200)" if verbose
|
328
|
+
when 202
|
329
|
+
"#{request_name} returned accepted, processing (Code 202)" if verbose
|
330
|
+
when 401
|
331
|
+
raise AuthError, "HTTP #{status_code}: The token provided could not authenticate.\n#{body}"
|
332
|
+
else
|
333
|
+
raise "HTTP #{status_code}: #{request_name} request to ABS failed!\n#{body}"
|
334
|
+
end
|
335
|
+
end
|
318
336
|
end
|
@@ -22,7 +22,7 @@ class NonstandardPooler
|
|
22
22
|
status['reserved_hosts'] || []
|
23
23
|
end
|
24
24
|
|
25
|
-
def self.retrieve(verbose, os_type, token, url, _user, _options)
|
25
|
+
def self.retrieve(verbose, os_type, token, url, _user, _options, ondemand = nil)
|
26
26
|
conn = Http.get_conn(verbose, url)
|
27
27
|
conn.headers['X-AUTH-TOKEN'] = token if token
|
28
28
|
|
data/lib/vmfloaty/utils.rb
CHANGED
@@ -79,40 +79,62 @@ class Utils
|
|
79
79
|
end
|
80
80
|
|
81
81
|
def self.pretty_print_hosts(verbose, service, hostnames = [], print_to_stderr = false)
|
82
|
+
fetched_data = self.get_host_data(verbose, service, hostnames)
|
83
|
+
fetched_data.each do |hostname, host_data|
|
84
|
+
case service.type
|
85
|
+
when 'ABS'
|
86
|
+
# For ABS, 'hostname' variable is the jobID
|
87
|
+
host_data['allocated_resources'].each do |vm_name, _i|
|
88
|
+
puts "- [JobID:#{host_data['request']['job']['id']}] #{vm_name['hostname']} (#{vm_name['type']}) <#{host_data['state']}>"
|
89
|
+
end
|
90
|
+
when 'Pooler'
|
91
|
+
tag_pairs = []
|
92
|
+
tag_pairs = host_data['tags'].map { |key, value| "#{key}: #{value}" } unless host_data['tags'].nil?
|
93
|
+
duration = "#{host_data['running']}/#{host_data['lifetime']} hours"
|
94
|
+
metadata = [host_data['template'], duration, *tag_pairs]
|
95
|
+
puts "- #{hostname}.#{host_data['domain']} (#{metadata.join(', ')})"
|
96
|
+
when 'NonstandardPooler'
|
97
|
+
line = "- #{host_data['fqdn']} (#{host_data['os_triple']}"
|
98
|
+
line += ", #{host_data['hours_left_on_reservation']}h remaining"
|
99
|
+
line += ", reason: #{host_data['reserved_for_reason']}" unless host_data['reserved_for_reason'].empty?
|
100
|
+
line += ')'
|
101
|
+
puts line
|
102
|
+
else
|
103
|
+
raise "Invalid service type #{service.type}"
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def self.get_host_data(verbose, service, hostnames = [])
|
109
|
+
result = {}
|
82
110
|
hostnames = [hostnames] unless hostnames.is_a? Array
|
83
111
|
hostnames.each do |hostname|
|
84
112
|
begin
|
85
113
|
response = service.query(verbose, hostname)
|
86
114
|
host_data = response[hostname]
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
115
|
+
if block_given?
|
116
|
+
yield host_data result
|
117
|
+
else
|
118
|
+
case service.type
|
119
|
+
when 'ABS'
|
120
|
+
# For ABS, 'hostname' variable is the jobID
|
121
|
+
if host_data['state'] == 'allocated' || host_data['state'] == 'filled'
|
122
|
+
result[hostname] = host_data
|
94
123
|
end
|
124
|
+
when 'Pooler'
|
125
|
+
result[hostname] = host_data
|
126
|
+
when 'NonstandardPooler'
|
127
|
+
result[hostname] = host_data
|
128
|
+
else
|
129
|
+
raise "Invalid service type #{service.type}"
|
95
130
|
end
|
96
|
-
when 'Pooler'
|
97
|
-
tag_pairs = []
|
98
|
-
tag_pairs = host_data['tags'].map { |key, value| "#{key}: #{value}" } unless host_data['tags'].nil?
|
99
|
-
duration = "#{host_data['running']}/#{host_data['lifetime']} hours"
|
100
|
-
metadata = [host_data['template'], duration, *tag_pairs]
|
101
|
-
puts "- #{hostname}.#{host_data['domain']} (#{metadata.join(', ')})"
|
102
|
-
when 'NonstandardPooler'
|
103
|
-
line = "- #{host_data['fqdn']} (#{host_data['os_triple']}"
|
104
|
-
line += ", #{host_data['hours_left_on_reservation']}h remaining"
|
105
|
-
line += ", reason: #{host_data['reserved_for_reason']}" unless host_data['reserved_for_reason'].empty?
|
106
|
-
line += ')'
|
107
|
-
puts line
|
108
|
-
else
|
109
|
-
raise "Invalid service type #{service.type}"
|
110
131
|
end
|
111
132
|
rescue StandardError => e
|
112
133
|
FloatyLogger.error("Something went wrong while trying to gather information on #{hostname}:")
|
113
134
|
FloatyLogger.error(e)
|
114
135
|
end
|
115
136
|
end
|
137
|
+
result
|
116
138
|
end
|
117
139
|
|
118
140
|
def self.pretty_print_status(verbose, service)
|
@@ -206,6 +228,9 @@ class Utils
|
|
206
228
|
# If the service is configured but some values are missing, use the top-level defaults to fill them in
|
207
229
|
service_config.merge! config['services'][options.service]
|
208
230
|
end
|
231
|
+
# No config file but service is declared on command line
|
232
|
+
elsif !config['services'] && options.service
|
233
|
+
service_config['type'] = options.service
|
209
234
|
end
|
210
235
|
|
211
236
|
# Prioritize an explicitly specified url, user, or token if the user provided one
|
data/lib/vmfloaty/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: vmfloaty
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.11.
|
4
|
+
version: 0.11.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brian Cain
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2020-08-
|
12
|
+
date: 2020-08-20 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: colorize
|