vmfloaty 0.11.0 → 0.11.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 248dd5c9a8890b8990a7dad8dd7a21f52c8a8c2b65112c55449a5b5d3ac818af
4
- data.tar.gz: 22cf2070b571a0feded3967308e6b11d42b5ea296d94be7c434a73454611f6df
3
+ metadata.gz: 5ebdafe4b60af0f238330584cbe7ee1a3a5258b1671b7805d45551c16c69465a
4
+ data.tar.gz: '002138e04b43f670d76d7f0311dbb4770e2153306874a527f0e537c59dfafc9e'
5
5
  SHA512:
6
- metadata.gz: 8cd836baeb4a37720024616f1ce113046fc6291cc73694edbaf74ee727648c1339ada9e004ba0d630822a315948d69bb9e6c67da1ec04df3ae079bf207a432c7
7
- data.tar.gz: 46e15ff3d3d1cecd68cb92ed3fcd5d8240f68f45f704dff9fbf1e87007cae7b95b2d6f9d4b08753979b2c82fa6f412534a93e3bb17b96fb052003e821b31cf94
6
+ metadata.gz: 23e7ea9dbb546740ea16418f7a5e00d184df44634bf5dc9ff5421907a7fac55ff65d7d74516f1762a805cf865ff941b97e474e20db101029b176b89f1946d662
7
+ data.tar.gz: 7ffa31b013b4d332a6e19f56b56a6f55560dbc6a65702cf1b81be7317bc1b59b434af674f7f54ddb13f4dc611e96e27c947aa6c4679031f32b3475b49c1e5e40
@@ -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
- puts "You have no running VMs on #{host}"
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
- puts "Your VMs on #{host}:"
106
- Utils.pretty_print_hosts(verbose, service, running_vms)
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
- puts 'You have no running VMs.'
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
- confirmed = agree('Delete all these VMs? [y/N]') unless force
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
- puts 'Scheduled the following VMs for deletion:'
261
- successes.each do |hostname|
262
- puts "- #{hostname}"
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
 
@@ -229,10 +229,10 @@ class ABS
229
229
 
230
230
  retries = 360
231
231
 
232
- raise AuthError, "HTTP #{res.status}: The token provided could not authenticate to the pooler.\n#{res_body}" if res.status == 401
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
 
@@ -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
- case service.type
89
- when 'ABS'
90
- # For ABS, 'hostname' variable is the jobID
91
- if host_data['state'] == 'allocated' || host_data['state'] == 'filled'
92
- host_data['allocated_resources'].each do |vm_name, _i|
93
- puts "- [JobID:#{host_data['request']['job']['id']}] #{vm_name['hostname']} (#{vm_name['type']}) <#{host_data['state']}>"
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Vmfloaty
4
- VERSION = '0.11.0'
4
+ VERSION = '0.11.1'
5
5
  end
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.0
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 00:00:00.000000000 Z
12
+ date: 2020-08-20 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: colorize