openstudio-aws 0.1.7 → 0.1.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +14 -13
  3. data/lib/openstudio-aws.rb +9 -7
  4. data/lib/openstudio/aws/aws.rb +53 -40
  5. data/lib/openstudio/aws/config.rb +0 -1
  6. data/lib/openstudio/aws/version.rb +2 -2
  7. data/lib/openstudio/lib/ami_list.rb +79 -0
  8. data/lib/openstudio/lib/openstudio_aws_instance.rb +138 -0
  9. data/lib/openstudio/lib/openstudio_aws_logger.rb +61 -0
  10. data/lib/openstudio/lib/openstudio_aws_methods.rb +232 -0
  11. data/lib/openstudio/lib/openstudio_aws_wrapper.rb +315 -0
  12. data/lib/openstudio/lib/os-aws.rb +77 -351
  13. data/spec/aws_instances/aws_spec_api.rb +70 -0
  14. data/spec/openstudio-aws/ami_list_spec.rb +37 -0
  15. data/spec/openstudio-aws/aws_methods_spec.rb +26 -0
  16. data/spec/openstudio-aws/lib_spec.rb +48 -0
  17. data/spec/reports/SPEC-OpenStudio-Aws-Aws-create-a-new-instance.xml +43 -0
  18. data/spec/reports/SPEC-OpenStudio-Aws-Aws-workers-before-server.xml +9 -0
  19. data/spec/reports/SPEC-OpenStudio-Aws-Aws.xml +7 -0
  20. data/spec/reports/SPEC-OpenStudio-Aws-Config-create-a-new-config.0.xml +9 -0
  21. data/spec/reports/SPEC-OpenStudio-Aws-Config-create-a-new-config.xml +9 -0
  22. data/spec/reports/SPEC-OpenStudio-Aws-Config.0.xml +7 -0
  23. data/spec/reports/SPEC-OpenStudio-Aws-Config.xml +7 -0
  24. data/spec/reports/SPEC-OpenStudioAmis-version-1.0.xml +13 -0
  25. data/spec/reports/SPEC-OpenStudioAmis-version-1.xml +13 -0
  26. data/spec/reports/SPEC-OpenStudioAmis.0.xml +7 -0
  27. data/spec/reports/SPEC-OpenStudioAmis.xml +7 -0
  28. data/spec/reports/SPEC-OpenStudioAwsMethods-processors.0.xml +11 -0
  29. data/spec/reports/SPEC-OpenStudioAwsMethods-processors.xml +11 -0
  30. data/spec/reports/SPEC-OpenStudioAwsMethods.0.xml +7 -0
  31. data/spec/reports/SPEC-OpenStudioAwsMethods.xml +7 -0
  32. data/spec/reports/SPEC-OpenStudioAwsWrapper-authenticated-session-availability.0.xml +11 -0
  33. data/spec/reports/SPEC-OpenStudioAwsWrapper-authenticated-session-availability.xml +11 -0
  34. data/spec/reports/SPEC-OpenStudioAwsWrapper-authenticated-session-new-instance.0.xml +9 -0
  35. data/spec/reports/SPEC-OpenStudioAwsWrapper-authenticated-session-new-instance.xml +9 -0
  36. data/spec/reports/SPEC-OpenStudioAwsWrapper-authenticated-session.0.xml +7 -0
  37. data/spec/reports/SPEC-OpenStudioAwsWrapper-authenticated-session.xml +7 -0
  38. data/spec/reports/SPEC-OpenStudioAwsWrapper-unauthenticated-session.0.xml +9 -0
  39. data/spec/reports/SPEC-OpenStudioAwsWrapper-unauthenticated-session.xml +9 -0
  40. data/spec/reports/SPEC-OpenStudioAwsWrapper.0.xml +7 -0
  41. data/spec/reports/SPEC-OpenStudioAwsWrapper.xml +7 -0
  42. metadata +70 -10
  43. data/lib/openstudio/aws/send_data.rb +0 -42
  44. data/spec/openstudio-aws/aws_spec.rb +0 -53
@@ -1,6 +1,6 @@
1
1
  # NOTE: Do not modify this file as it is copied over. Modify the source file and rerun rake import_files
2
2
  ######################################################################
3
- # Copyright (c) 2008-2013, Alliance for Sustainable Energy.
3
+ # Copyright (c) 2008-2014, Alliance for Sustainable Energy.
4
4
  # All rights reserved.
5
5
  #
6
6
  # This library is free software; you can redistribute it and/or
@@ -36,7 +36,10 @@
36
36
  #
37
37
  ######################################################################
38
38
 
39
- require 'aws-sdk'
39
+ require_relative 'openstudio_aws_wrapper'
40
+ require_relative 'openstudio_aws_instance'
41
+ require_relative 'ami_list'
42
+ require 'aws-sdk-core'
40
43
  require 'json'
41
44
  require 'logger'
42
45
  require 'net/http'
@@ -44,10 +47,17 @@ require 'net/scp'
44
47
  require 'net/ssh'
45
48
  require 'tempfile'
46
49
  require 'time'
50
+ require 'base64'
47
51
 
48
52
  def error(code, msg)
49
- puts ({:error => {:code => code, :message => msg},
50
- :arguments => ARGV[2..-1]}.to_json)
53
+ puts (
54
+ {
55
+ :error => {
56
+ :code => code, :message => msg
57
+ },
58
+ :arguments => ARGV[2..-1]
59
+ }.to_json
60
+ )
51
61
  exit(1)
52
62
  end
53
63
 
@@ -71,15 +81,10 @@ if ARGV[4].empty?
71
81
  error(-1, 'Missing command argument')
72
82
  end
73
83
 
74
- AWS.config(
75
- :access_key_id => ARGV[0],
76
- :secret_access_key => ARGV[1],
77
- :region => ARGV[2],
78
- :ssl_verify_peer => false
79
- )
84
+ Aws.config = {:access_key_id => ARGV[0], :secret_access_key => ARGV[1], :region => ARGV[2], :ssl_verify_peer => false}
80
85
 
81
86
  if ARGV[3] == 'EC2'
82
- @aws = AWS::EC2.new
87
+ @aws = Aws::EC2.new
83
88
  elsif ARGV[3] == 'CloudWatch'
84
89
  @aws = AWS::CloudWatch.new
85
90
  else
@@ -95,257 +100,20 @@ end
95
100
 
96
101
  OPENSTUDIO_VERSION = '1.1.4' unless defined?(OPENSTUDIO_VERSION)
97
102
 
98
- if (!defined?(@server_image_id) || !defined?(@worker_image_id))
99
- resp = Net::HTTP.get_response('developer.nrel.gov','/downloads/buildings/openstudio/rsrc/amis.json')
100
- if resp.code == '200'
101
- result = JSON.parse(resp.body)
102
- version = result.has_key?(OPENSTUDIO_VERSION) ? OPENSTUDIO_VERSION : 'default'
103
+ SERVER_PEM_FILENAME = File.expand_path("~/openstudio-server.pem")
103
104
 
104
- @server_image_id = result[version]['server']
105
+ if (!defined?(@server_image_id) || !defined?(@worker_image_id))
106
+ amis = OpenStudioAmis.new(1, OPENSTUDIO_VERSION)
107
+
108
+ if amis
109
+ @server_image_id = amis['server']
105
110
  if ARGV.length >= 6 && @params['instance_type'] == 'cc2.8xlarge'
106
- @worker_image_id = result[version]['cc2worker']
111
+ @worker_image_id = amis['cc2worker']
107
112
  else
108
- @worker_image_id = result[version]['worker']
113
+ @worker_image_id = amis['worker']
109
114
  end
110
115
  else
111
- error(resp.code, 'Unable to download AMI IDs')
112
- end
113
- end
114
-
115
- def create_struct(instance, procs)
116
- instance_struct = Struct.new(:instance, :id, :ip, :dns, :procs)
117
- return instance_struct.new(instance, instance.instance_id, instance.ip_address, instance.dns_name, procs)
118
- end
119
-
120
- def find_processors(instance)
121
- processors = 1
122
- case instance
123
- when 'cc2.8xlarge'
124
- processors = 16
125
- when 'c1.xlarge'
126
- processors = 8
127
- when 'm2.4xlarge'
128
- processors = 8
129
- when 'm2.2xlarge'
130
- processors = 4
131
- when 'm2.xlarge'
132
- processors = 2
133
- when 'm1.xlarge'
134
- processors = 4
135
- when 'm1.large'
136
- processors = 2
137
- when 'm3.xlarge'
138
- processors = 2
139
- when 'm3.2xlarge'
140
- processors = 4
141
- end
142
-
143
- return processors
144
- end
145
-
146
- def launch_server
147
- user_data = File.read(File.expand_path(File.dirname(__FILE__))+'/server_script.sh')
148
- @logger.info("server user_data #{user_data.inspect}")
149
- @server = @aws.instances.create(:image_id => @server_image_id,
150
- :key_pair => @key_pair,
151
- :security_groups => @group,
152
- :user_data => user_data,
153
- :instance_type => @server_instance_type)
154
- @server.add_tag('Name', :value => "OpenStudio-Server V#{OPENSTUDIO_VERSION}")
155
- sleep 5 while @server.status == :pending
156
- if @server.status != :running
157
- error(-1, "Server status: #{@server.status}")
158
- end
159
-
160
- processors = find_processors(@server_instance_type)
161
- #processors = send_command(@server.ip_address, 'nproc | tr -d "\n"')
162
- #processors = 0 if processors.nil? # sometimes this returns nothing, so put in a default
163
- @server = create_struct(@server, processors)
164
- end
165
-
166
- def launch_workers(num, server_ip)
167
- user_data = File.read(File.expand_path(File.dirname(__FILE__))+'/worker_script.sh.template')
168
- user_data.gsub!(/SERVER_IP/, server_ip)
169
- user_data.gsub!(/SERVER_HOSTNAME/, 'master')
170
- user_data.gsub!(/SERVER_ALIAS/, '')
171
- @logger.info("worker user_data #{user_data.inspect}")
172
- instances = []
173
- num.times do
174
- worker = @aws.instances.create(:image_id => @worker_image_id,
175
- :key_pair => @key_pair,
176
- :security_groups => @group,
177
- :user_data => user_data,
178
- :instance_type => @worker_instance_type)
179
- worker.add_tag('Name', :value => "OpenStudio-Worker V#{OPENSTUDIO_VERSION}")
180
- instances.push(worker)
181
- end
182
- sleep 5 while instances.any? { |instance| instance.status == :pending }
183
- if instances.any? { |instance| instance.status != :running }
184
- error(-1, "Worker status: Not running")
185
- end
186
-
187
- # todo: fix this - sometimes returns nil
188
- processors = find_processors(@worker_instance_type)
189
- #processors = send_command(instances[0].ip_address, 'nproc | tr -d "\n"')
190
- #processors = 0 if processors.nil? # sometimes this returns nothing, so put in a default
191
- instances.each { |instance| @workers.push(create_struct(instance, processors)) }
192
- end
193
-
194
- def upload_file(host, local_path, remote_path)
195
- retries = 0
196
- begin
197
- Net::SCP.start(host, 'ubuntu', :key_data => [@private_key]) do |scp|
198
- scp.upload! local_path, remote_path
199
- end
200
- rescue SystemCallError, Timeout::Error => e
201
- # port 22 might not be available immediately after the instance finishes launching
202
- return if retries == 5
203
- retries += 1
204
- sleep 1
205
- retry
206
- rescue
207
- # Unknown upload error, retry
208
- return if retries == 5
209
- retries += 1
210
- sleep 1
211
- retry
212
- end
213
- end
214
-
215
-
216
- def send_command(host, command)
217
- #retries = 0
218
- begin
219
- output = ''
220
- Net::SSH.start(host, 'ubuntu', :key_data => [@private_key]) do |ssh|
221
- response = ssh.exec!(command)
222
- output += response if !response.nil?
223
- end
224
- return output
225
- rescue Net::SSH::HostKeyMismatch => e
226
- e.remember_host!
227
- # key mismatch, retry
228
- #return if retries == 5
229
- #retries += 1
230
- sleep 1
231
- retry
232
- rescue Net::SSH::AuthenticationFailed
233
- error(-1, "Incorrect private key")
234
- rescue SystemCallError, Timeout::Error => e
235
- # port 22 might not be available immediately after the instance finishes launching
236
- #return if retries == 5
237
- #retries += 1
238
- sleep 1
239
- retry
240
- rescue Exception => e
241
- puts e.message
242
- puts e.backtrace.inspect
243
- end
244
- end
245
-
246
- #======================= send command ======================#
247
- # Send a command through SSH Shell to an instance.
248
- # Need to pass instance object and the command as a string.
249
- def shell_command(host, command)
250
- begin
251
- @logger.info("ssh_command #{command}")
252
- Net::SSH.start(host, 'ubuntu', :key_data => [@private_key]) do |ssh|
253
- channel = ssh.open_channel do |ch|
254
- ch.exec "#{command}" do |ch, success|
255
- raise "could not execute #{command}" unless success
256
-
257
- # "on_data" is called when the process writes something to stdout
258
- ch.on_data do |c, data|
259
- #$stdout.print data
260
- @logger.info("#{data.inspect}")
261
- end
262
-
263
- # "on_extended_data" is called when the process writes something to stderr
264
- ch.on_extended_data do |c, type, data|
265
- #$stderr.print data
266
- @logger.info("#{data.inspect}")
267
- end
268
- end
269
- end
270
- end
271
- rescue Net::SSH::HostKeyMismatch => e
272
- e.remember_host!
273
- @logger.info("key mismatch, retry")
274
- sleep 1
275
- retry
276
- rescue SystemCallError, Timeout::Error => e
277
- # port 22 might not be available immediately after the instance finishes launching
278
- sleep 1
279
- @logger.info("Not Yet")
280
- retry
281
- end
282
- end
283
-
284
- def wait_command(host, command)
285
- begin
286
- flag = 0
287
- while flag == 0 do
288
- @logger.info("wait_command #{command}")
289
- Net::SSH.start(host, 'ubuntu', :key_data => [@private_key]) do |ssh|
290
- channel = ssh.open_channel do |ch|
291
- ch.exec "#{command}" do |ch, success|
292
- raise "could not execute #{command}" unless success
293
-
294
- # "on_data" is called when the process writes something to stdout
295
- ch.on_data do |c, data|
296
- @logger.info("#{data.inspect}")
297
- if data.chomp == "true"
298
- @logger.info("wait_command #{command} is true")
299
- flag = 1
300
- else
301
- sleep 5
302
- end
303
- end
304
-
305
- # "on_extended_data" is called when the process writes something to stderr
306
- ch.on_extended_data do |c, type, data|
307
- @logger.info("#{data.inspect}")
308
- if data == "true"
309
- @logger.info("wait_command #{command} is true")
310
- flag = 1
311
- else
312
- sleep 5
313
- end
314
- end
315
- end
316
- end
317
- end
318
- end
319
- rescue Net::SSH::HostKeyMismatch => e
320
- e.remember_host!
321
- @logger.info("key mismatch, retry")
322
- sleep 1
323
- retry
324
- rescue SystemCallError, Timeout::Error => e
325
- # port 22 might not be available immediately after the instance finishes launching
326
- sleep 1
327
- @logger.info("Not Yet")
328
- retry
329
- end
330
- end
331
-
332
- def download_file(host, remote_path, local_path)
333
- retries = 0
334
- begin
335
- Net::SCP.start(host, 'ubuntu', :key_data => [@private_key]) do |scp|
336
- scp.download! remote_path, local_path
337
- end
338
- rescue SystemCallError, Timeout::Error => e
339
- # port 22 might not be available immediately after the instance finishes launching
340
- return if retries == 5
341
- retries += 1
342
- sleep 1
343
- retry
344
- rescue
345
- return if retries == 5
346
- retries += 1
347
- sleep 1
348
- retry
116
+ error(-1, 'Unable to download AMI IDs')
349
117
  end
350
118
  end
351
119
 
@@ -354,20 +122,29 @@ begin
354
122
  @logger.info("initialized")
355
123
  case ARGV[4]
356
124
  when 'describe_availability_zones'
357
- resp = @aws.client.describe_availability_zones
358
- puts resp.data.to_json
359
- @logger.info("availability_zones #{resp.data.to_json}")
125
+ os_aws = OpenStudioAwsWrapper.new
126
+ resp = os_aws.describe_availability_zones_json
127
+ puts resp
128
+ @logger.info("availability_zones #{resp}")
360
129
  when 'total_instances'
361
- resp = @aws.client.describe_instance_status
362
- puts ({:total_instances => resp.data[:instance_status_set].length,
363
- :region => ARGV[2]}.to_json)
130
+ os_aws = OpenStudioAwsWrapper.new
131
+ resp = os_aws.describe_total_instances_json
132
+ puts resp
364
133
  when 'instance_status'
134
+ os_aws = OpenStudioAwsWrapper.new
135
+
365
136
  resp = nil
366
137
  if ARGV.length < 6
367
- resp = @aws.client.describe_instance_status
138
+ resp = os_aws.describe_instance_status
368
139
  else
369
- resp = @aws.client.describe_instance_status({:instance_ids => [@params['instance_id']]})
140
+ resp = os_aws.describe_instance_status({:instance_ids => [@params['instance_id']]})
370
141
  end
142
+ #resp = nil
143
+ #if ARGV.length < 6
144
+ # resp = @aws.client.describe_instance_status
145
+ #else
146
+ # resp = @aws.client.describe_instance_status({:instance_ids => [@params['instance_id']]})
147
+ #end
371
148
  output = Hash.new
372
149
  resp.data[:instance_status_set].each { |instance|
373
150
  output[instance[:instance_id]] = instance[:instance_state][:name]
@@ -377,34 +154,37 @@ begin
377
154
  if ARGV.length < 6
378
155
  error(-1, 'Invalid number of args')
379
156
  end
157
+ os_aws = OpenStudioAwsWrapper.new
158
+ os_aws.create_or_retrieve_security_group("openstudio-server-sg-v1")
159
+ os_aws.create_or_retrieve_key_pair
380
160
 
381
- @timestamp = Time.now.to_i
161
+ # this step is really important because this is read from the worker nodes. We
162
+ # should not be printing this to screen nor putting into the log in case the
163
+ # user is starting to used shared keys.
164
+ os_aws.save_private_key(SERVER_PEM_FILENAME)
382
165
 
383
- # find if an existing openstudio-server-vX security group exists and use that
384
- @group = @aws.security_groups.filter('group-name', 'openstudio-server-sg-v1').first
385
- if @group.nil?
386
- @group = @aws.security_groups.create('openstudio-server-sg-v1')
387
- @group.allow_ping() # allow ping
388
- @group.authorize_ingress(:tcp, 1..65535) # all traffic
389
- end
390
- @logger.info("server_group #{@group}")
391
166
  @server_instance_type = @params['instance_type']
167
+ begin
168
+ os_aws.launch_server(@server_image_id, @server_instance_type)
169
+ rescue Exception => e
170
+ error(-1, "Server status: #{e.message}")
171
+ end
392
172
 
393
- @key_pair = @aws.key_pairs.create("key-pair-#{@timestamp}")
394
- @private_key = @key_pair.private_key
173
+ puts os_aws.server.to_os_hash.to_json
174
+ when 'launch_workers'
175
+ @timestamp = @params['timestamp'] #timestamp is renamed to groupuuid in the backend
395
176
 
396
- launch_server()
177
+ os_aws = OpenStudioAwsWrapper.new(nil, @timestamp)
178
+ os_aws.find_server(@timestamp) # really the group id
179
+ os_aws.create_or_retrieve_security_group("openstudio-worker-sg-v1")
180
+
181
+ # find the private key in the users home directory, or crash
182
+ if File.exists?(SERVER_PEM_FILENAME)
183
+ os_aws.create_or_retrieve_key_pair(nil, SERVER_PEM_FILENAME)
184
+ else
185
+ raise "Could not find previous private key which should be here: #{SERVER_PEM_FILENAME}"
186
+ end
397
187
 
398
- puts ({:timestamp => @timestamp,
399
- :private_key => @private_key,
400
- :server => {
401
- :id => @server.id,
402
- :ip => 'http://' + @server.ip,
403
- :dns => @server.dns,
404
- :procs => @server.procs
405
- }}.to_json)
406
- @logger.info("server info #{({:timestamp => @timestamp, :private_key => @private_key, :server => {:id => @server.id, :ip => @server.ip, :dns => @server.dns, :procs => @server.procs}}.to_json)}")
407
- when 'launch_workers'
408
188
  if ARGV.length < 6
409
189
  error(-1, 'Invalid number of args')
410
190
  end
@@ -412,73 +192,19 @@ begin
412
192
  error(-1, 'Invalid number of worker nodes, must be greater than 0')
413
193
  end
414
194
 
415
- @workers = []
416
- @timestamp = @params['timestamp']
417
-
418
- # find if an existing openstudio-server-vX security group exists and use that
419
- @group = @aws.security_groups.filter('group-name', 'openstudio-worker-sg-v1').first
420
- if @group.nil?
421
- @group = @aws.security_groups.create('openstudio-worker-sg-v1')
422
- @group.allow_ping() # allow ping
423
- @group.authorize_ingress(:tcp, 1..65535) # all traffic
424
- end
425
- @logger.info("worker_group #{@group}")
426
- @key_pair = @aws.key_pairs.filter('key-name', "key-pair-#{@timestamp}").first
427
- @private_key = File.read(@params['private_key'])
428
195
  @worker_instance_type = @params['instance_type']
429
- @server = @aws.instances[@params['server_id']]
430
- error(-1, 'Server node does not exist') unless @server.exists?
431
- @server = create_struct(@server, @params['server_procs'])
432
-
433
- launch_workers(@params['num'], @server.ip)
434
- #@workers.push(create_struct(@aws.instances['i-xxxxxxxx'], 1))
435
- #processors = send_command(@workers[0].ip, 'nproc | tr -d "\n"')
436
- #@workers[0].procs = processors
196
+ begin
197
+ # this will launch and configure with threads inside os_aws
198
+ os_aws.launch_workers(@worker_image_id, @worker_instance_type, @params['num'])
199
+ rescue Exception => e
200
+ error(-1, "Server status: #{e.message}")
201
+ end
437
202
 
438
203
  #wait for user_data to complete execution
439
- @logger.info("server user_data")
440
- wait_command(@server.ip, '[ -e /home/ubuntu/user_data_done ] && echo "true"')
441
- @logger.info("worker user_data")
442
- @workers.each { |worker| wait_command(worker.ip, '[ -e /home/ubuntu/user_data_done ] && echo "true"') }
443
- #wait_command(@workers.first.ip, "[ -e /home/ubuntu/user_data_done ] && echo 'true'")
444
-
445
-
446
- ips = "master|#{@server.ip}|#{@server.dns}|#{@server.procs}|ubuntu|ubuntu\n"
447
- @workers.each { |worker| ips << "worker|#{worker.ip}|#{worker.dns}|#{worker.procs}|ubuntu|ubuntu|true\n" }
448
- file = Tempfile.new('ip_addresses')
449
- file.write(ips)
450
- file.close
451
- upload_file(@server.ip, file.path, 'ip_addresses')
452
- file.unlink
453
- @logger.info("ips #{ips}")
454
- shell_command(@server.ip, 'chmod 664 /home/ubuntu/ip_addresses')
455
- shell_command(@server.ip, '~/setup-ssh-keys.sh')
456
- shell_command(@server.ip, '~/setup-ssh-worker-nodes.sh ip_addresses')
457
-
458
- mongoid = File.read(File.expand_path(File.dirname(__FILE__))+'/mongoid.yml.template')
459
- mongoid.gsub!(/SERVER_IP/, @server.ip)
460
- file = Tempfile.new('mongoid.yml')
461
- file.write(mongoid)
462
- file.close
463
- upload_file(@server.ip, file.path, '/mnt/openstudio/rails-models/mongoid.yml')
464
- @workers.each { |worker| upload_file(worker.ip, file.path, '/mnt/openstudio/rails-models/mongoid.yml') }
465
- file.unlink
466
-
467
- # Does this command crash it?
468
- shell_command(@server.ip, 'chmod 664 /mnt/openstudio/rails-models/mongoid.yml')
469
- @workers.each { |worker| shell_command(worker.ip, 'chmod 664 /mnt/openstudio/rails-models/mongoid.yml') }
470
-
471
- worker_json = []
472
- @workers.each { |worker|
473
- worker_json.push({
474
- :id => worker.id,
475
- :ip => 'http://' + worker.ip,
476
- :dns => worker.dns,
477
- :procs => worker.procs
478
- })
479
- }
480
- puts ({:workers => worker_json}.to_json)
481
- @logger.info("workers #{({:workers => worker_json}.to_json)}")
204
+ os_aws.configure_server_and_workers
205
+
206
+ # have to print to screen for c++ to grab the information
207
+ puts os_aws.to_os_worker_hash.to_json
482
208
  when 'terminate_session'
483
209
  if ARGV.length < 6
484
210
  error(-1, 'Invalid number of args')