openstudio-aws 0.4.0.alpha2 → 0.4.0.alpha3

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
  SHA1:
3
- metadata.gz: eba77b1f1302604cb57c69a087796ead6aaf2c98
4
- data.tar.gz: 113a23d7859a8da882a7f5e426098cbf6ed61986
3
+ metadata.gz: 2f024e917704db3001f98d70663da27d0a998d54
4
+ data.tar.gz: 43af587c2f58ff2690c1a91ccd242b4f133c0171
5
5
  SHA512:
6
- metadata.gz: b01c424a5369cddce55c78adfb87b3c330158faa4e0b25f7148106c5947db6f8df7dbd91e4d1e3d4749e6548476743b5edd5865477e3b864b6d034539a3c8bab
7
- data.tar.gz: 99026903cb962cbb0e8990aa97236ce645336346d1977be7027a4aee58757768d835b4869957dd5965f4629ee0f17dc2da1f62ede3c3fb803873253181e87333
6
+ metadata.gz: 8f7b216034b3aaee08482319454aef815a9b3437c21e1dc2821fe2393cf483179c870e3eaf0d05987cd82d62d1dca795cce4a287d871ffcd622cb0f11c56a5d2
7
+ data.tar.gz: 3d087837a34a9c847b4f72100ac94ca1328ea2e88909009fa4eb44d7f2db6750010a9f75b14938d96b111e6513adea75c77d4f4d7ed9260daab02dcae156d4f0
data/CHANGELOG.md CHANGED
@@ -1,6 +1,11 @@
1
1
  OpenStudio AWS Gem Change Log
2
2
  ==================================
3
3
 
4
+ Version 0.4.0.alpha3
5
+ -------------
6
+ * Load the key name and security groups from the AWS instance information.
7
+ * Add method on Aws to get the group_uuid
8
+
4
9
  Version 0.4.0.alpha2
5
10
  -------------
6
11
  * Load worker keys from disk (if they exist) when constructing the OpenStudioAwsWrapper class
@@ -138,7 +138,7 @@ module OpenStudio
138
138
  @os_aws.private_key_file_name = options[:private_key_file_name]
139
139
  else
140
140
  # Save the private key if you did not pass in an already existing key_pair_name
141
- @os_aws.save_private_key(@save_directory)
141
+ @os_aws.save_private_key @save_directory
142
142
  end
143
143
 
144
144
  server_options = {
@@ -150,32 +150,16 @@ module OpenStudio
150
150
 
151
151
  # save the worker pem and public to the directory
152
152
  # presently, this will always overwrite the worker key, is that okay? Is this really needed later?
153
- @os_aws.save_worker_keys(@save_directory)
154
-
155
- # if instance_data[:ebs_volume_id]
156
- # server_options[:ebs_volume_id] = instance_data[:ebs_volume_id]
157
- # end
153
+ @os_aws.save_worker_keys @save_directory
158
154
 
159
155
  @os_aws.launch_server(options[:image_id], options[:instance_type], server_options)
160
156
  end
161
157
 
162
- # Write out to the terminal the connection information for the servers and workers
158
+ # create workers after the server has been created.
163
159
  #
164
- # @return [nil] Only prints to the screen. No return is expected
165
- def print_connection_info
166
- # Print out some debugging commands (probably work on mac/linux only)
167
- puts ''
168
- puts 'Server SSH Command:'
169
- puts "ssh -i #{@os_aws.private_key_file_name} ubuntu@#{@os_aws.server.data[:dns]}"
170
- if @os_aws.workers.size > 0
171
- puts ''
172
- puts 'Worker SSH Command:'
173
- @os_aws.workers.each do |worker|
174
- puts "ssh -i #{@os_aws.private_key_file_name} ubuntu@#{worker.data[:dns]}"
175
- end
176
- end
177
- end
178
-
160
+ # @param number_of_instances [Integer] Number of worker instances to create
161
+ # @param options [Hash]
162
+ # @option options [String] :instance_type Type of server to start (e.g. m3.medium, m3.xlarge, etc.)
179
163
  def create_workers(number_of_instances, options = {}, user_id = 'unknown_user')
180
164
  defaults = {
181
165
  instance_type: 'm2.4xlarge',
@@ -226,13 +210,27 @@ module OpenStudio
226
210
  @os_aws.configure_server_and_workers
227
211
  end
228
212
 
213
+ # Write out to the terminal the connection information for the servers and workers
214
+ #
215
+ # @return [nil] Only prints to the screen. No return is expected
216
+ def print_connection_info
217
+ # Print out some debugging commands (probably work on mac/linux only)
218
+ puts ''
219
+ puts 'Server SSH Command:'
220
+ puts "ssh -i #{@os_aws.private_key_file_name} ubuntu@#{@os_aws.server.data[:dns]}"
221
+ if @os_aws.workers.size > 0
222
+ puts ''
223
+ puts 'Worker SSH Command:'
224
+ @os_aws.workers.each do |worker|
225
+ puts "ssh -i #{@os_aws.private_key_file_name} ubuntu@#{worker.data[:dns]}"
226
+ end
227
+ end
228
+ end
229
+
229
230
  # Return information on the cluster instances as a hash. This includes IP addresses, host names, number of processors, etc.
230
231
  # @return [Hash] Data about the configured cluster
231
232
  def cluster_info
232
- h = @os_aws.server.to_os_hash
233
- h[:workers] = @os_aws.to_os_worker_hash[:workers]
234
-
235
- h
233
+ @os_aws.to_os_hash
236
234
  end
237
235
 
238
236
  # Save a JSON with information about the cluster that was configured.
@@ -416,6 +414,13 @@ module OpenStudio
416
414
  image
417
415
  end
418
416
 
417
+ # Return the Group UUID as defined in the AWS wrapper
418
+ #
419
+ # @return [String] UUID
420
+ def group_uuid
421
+ @os_aws.group_uuid
422
+ end
423
+
419
424
  private
420
425
 
421
426
  def os_aws_file_location
@@ -1,5 +1,5 @@
1
1
  module OpenStudio
2
2
  module Aws
3
- VERSION = '0.4.0.alpha2'
3
+ VERSION = '0.4.0.alpha3'
4
4
  end
5
5
  end
@@ -65,7 +65,7 @@ class OpenStudioAwsWrapper
65
65
  work_dir = options[:save_directory] || '.'
66
66
  if File.exist?(File.join(work_dir, 'ec2_worker_key.pem')) && File.exist?(File.join(work_dir, 'ec2_worker_key.pub'))
67
67
  logger.info "Worker keys already exist, loading from #{work_dir}"
68
- @worker_keys = SSHKey.new(File.read(File.join(work_dir, 'ec2_worker_key.pem')))
68
+ load_worker_key(File.join(work_dir, 'ec2_worker_key.pem'))
69
69
  else
70
70
  logger.info 'Generating new worker keys'
71
71
  @worker_keys = SSHKey.generate
@@ -338,13 +338,24 @@ class OpenStudioAwsWrapper
338
338
  @private_key = File.read(filename)
339
339
  end
340
340
 
341
+ # Load the worker key for communicating between the server and worker instances on AWS. The public key
342
+ # will be automatically created when loading the private key
343
+ #
344
+ # @param private_key_filename [String] Fully qualified path to the worker private key
345
+ def load_worker_key(private_key_filename)
346
+ logger.info "Loading worker keys from #{private_key_filename}"
347
+ @worker_keys_filename = private_key_filename
348
+ @worker_keys = SSHKey.new(File.read(@worker_keys_filename))
349
+ end
350
+
351
+ # Save the private key to disk
341
352
  def save_private_key(directory = '.', filename = 'ec2_server_key.pem')
342
353
  if @private_key
343
354
  @private_key_file_name = File.expand_path "#{directory}/#{filename}"
344
355
  logger.info "Saving server private key in #{@private_key_file_name}"
345
356
  File.open(@private_key_file_name, 'w') { |f| f << @private_key }
346
357
  logger.info 'Setting permissions of server private key to 0600'
347
-
358
+ File.chmod(0600, @private_key_file_name)
348
359
  else
349
360
  fail "No private key found in which to persist with filename #{filename}"
350
361
  end
@@ -352,11 +363,11 @@ class OpenStudioAwsWrapper
352
363
 
353
364
  # save off the worker public/private keys that were created
354
365
  def save_worker_keys(directory = '.')
355
- wk = "#{directory}/ec2_worker_key.pem"
356
- logger.info "Saving worker private key in #{wk}"
357
- File.open(wk, 'w') { |f| f << @worker_keys.private_key }
366
+ @worker_keys_filename = "#{directory}/ec2_worker_key.pem"
367
+ logger.info "Saving worker private key in #{@worker_keys_filename}"
368
+ File.open(@worker_keys_filename, 'w') { |f| f << @worker_keys.private_key }
358
369
  logger.info 'Setting permissions of worker private key to 0600'
359
- File.chmod(0600, wk)
370
+ File.chmod(0600, @worker_keys_filename)
360
371
 
361
372
  wk = "#{directory}/ec2_worker_key.pub"
362
373
  logger.info "Saving worker public key in #{wk}"
@@ -403,7 +414,6 @@ class OpenStudioAwsWrapper
403
414
  logger.info("worker user_data #{user_data.inspect}")
404
415
 
405
416
  # thread the launching of the workers
406
-
407
417
  num.times do
408
418
  @workers << OpenStudioAwsInstance.new(@aws, :worker, @key_pair_name, @security_groups, @group_uuid,
409
419
  @private_key, @private_key_file_name, @proxy)
@@ -458,14 +468,19 @@ class OpenStudioAwsWrapper
458
468
  end
459
469
 
460
470
  # method to query the amazon api to find the server (if it exists), based on the group id
461
- # if it is found, then it will set the @server member variable.
471
+ # if it is found, then it will set the @server instance variable. The security groups are assigned from the
472
+ # server node information on AWS if the security groups have not been initialized yet.
473
+ #
462
474
  # Note that the information around keys and security groups is pulled from the instance information.
475
+ # @param server_data_hash [Hash] Server data
476
+ # @option server_data_hash [String] :group_id Group ID of the analysis
477
+ # @option server_data_hash [String] :server.private_key_file_name Name of the private key to communicate to the server
463
478
  def find_server(server_data_hash)
464
479
  @group_uuid = server_data_hash[:group_id] || @group_uuid
465
480
  load_private_key(server_data_hash[:server][:private_key_file_name])
466
481
 
467
482
  logger.info "Finding the server for GroupUUID of #{group_uuid}"
468
- fail 'no GroupUUID defined either in member variable or method argument' if group_uuid.nil?
483
+ fail 'no GroupUUID defined either in member variable or method argument' if @group_uuid.nil?
469
484
 
470
485
  # This should really just be a single call to describe running instances
471
486
  @server = nil
@@ -476,7 +491,17 @@ class OpenStudioAwsWrapper
476
491
  if !@server
477
492
  if resp
478
493
  logger.info "Server found and loading data into object [instance id is #{resp[:instance_id]}]"
479
- @server = OpenStudioAwsInstance.new(@aws, :server, resp[:key_name], resp[:security_groups].first[:group_name], group_uuid, @private_key, @private_key_file_name, @proxy)
494
+
495
+ sg = resp[:security_groups].map { |s| s[:group_id] }
496
+ # Set the security groups of the object if these groups haven't been assigned yet.
497
+ @security_groups = sg if @security_groups.empty?
498
+ logger.info "The security groups in aws wrapper are #{@security_groups}"
499
+
500
+ # set the key name from AWS if it isn't yet assigned
501
+ logger.info 'Setting the keyname in the aws wrapper'
502
+ @key_pair_name = resp[:key_name] unless @key_pair_name
503
+
504
+ @server = OpenStudioAwsInstance.new(@aws, :server, @key_pair_name, sg, @group_uuid, @private_key, @private_key_file_name, @proxy)
480
505
 
481
506
  @server.load_instance_data(resp)
482
507
  end
@@ -487,12 +512,12 @@ class OpenStudioAwsWrapper
487
512
  logger.info 'could not find a running server instance'
488
513
  end
489
514
 
490
- # find the workers
515
+ # Find the worker instances.
491
516
  if @workers.size == 0
492
517
  resp = describe_running_instances(group_uuid, :worker)
493
518
  if resp
494
519
  resp.each do |r|
495
- @workers << OpenStudioAwsInstance.new(@aws, :worker, r[:key_name], r[:security_groups].first[:group_name], group_uuid, @private_key, @private_key_file_name, @proxy)
520
+ @workers << OpenStudioAwsInstance.new(@aws, :worker, r[:key_name], r[:security_groups].map { |s| s[:group_id] }, @group_uuid, @private_key, @private_key_file_name, @proxy)
496
521
  @workers.last.load_instance_data(r)
497
522
  end
498
523
  end
@@ -500,6 +525,10 @@ class OpenStudioAwsWrapper
500
525
  logger.info 'Worker nodes are already defined'
501
526
  end
502
527
 
528
+ # set the private key from the hash
529
+ load_private_key server_data_hash[:server][:private_key_file_name]
530
+ load_worker_key server_data_hash[:server][:worker_private_key_file_name]
531
+
503
532
  # Really don't need to return anything because this sets the class instance variable
504
533
  @server
505
534
  end
@@ -558,23 +587,23 @@ class OpenStudioAwsWrapper
558
587
  amis
559
588
  end
560
589
 
561
- def to_os_worker_hash
562
- worker_hash = []
563
- @workers.each do |worker|
564
- worker_hash.push(
590
+ # save off the instance configuration and instance information into a JSON file for later use
591
+ def to_os_hash
592
+ h = @server.to_os_hash
593
+
594
+ h[:server][:worker_private_key_file_name] = @worker_keys_filename
595
+ h[:workers] = @workers.map do |worker|
596
+ {
565
597
  id: worker.data.id,
566
598
  ip: "http://#{worker.data.ip}",
567
599
  dns: worker.data.dns,
568
600
  procs: worker.data.procs,
569
601
  private_key_file_name: worker.private_key_file_name,
570
602
  private_ip_address: worker.private_ip_address
571
- )
603
+ }
572
604
  end
573
605
 
574
- out = { workers: worker_hash }
575
- logger.info out
576
-
577
- out
606
+ h
578
607
  end
579
608
 
580
609
  # take the base version and increment the patch until
@@ -290,4 +290,58 @@ describe OpenStudio::Aws::Aws do
290
290
  expect(@aws_2.os_aws.worker_keys.public_key).not_to be_nil
291
291
  end
292
292
  end
293
+
294
+ context 'stateful creation of server and worker' do
295
+ before(:all) do
296
+ @config = OpenStudio::Aws::Config.new
297
+ @aws = OpenStudio::Aws::Aws.new
298
+ end
299
+
300
+ it 'should create the server and save the state' do
301
+ options = {
302
+ instance_type: 'm3.medium',
303
+ image_id: SERVER_AMI,
304
+ tags: [
305
+ 'ci_tests=true',
306
+ 'ServerOnly=true'
307
+ ]
308
+ }
309
+
310
+ test_pem_file = 'ec2_server_key.pem'
311
+ FileUtils.rm_f test_pem_file if File.exist? test_pem_file
312
+ FileUtils.rm_f 'server_data.json' if File.exist? 'server_data.json'
313
+
314
+ @aws.create_server(options)
315
+ @aws.save_cluster_info 'server_data.json'
316
+
317
+ h = @aws.os_aws.server.to_os_hash
318
+ expect(h[:group_id]).to be_a String
319
+ expect(h[:group_id]).to match /^[\d\S]{32}$/
320
+ expect(h[:location]).to eq 'AWS'
321
+ end
322
+
323
+ it 'should load server information from json and launch worker' do
324
+ aws2 = OpenStudio::Aws::Aws.new
325
+ aws2.load_instance_info_from_file('server_data.json')
326
+
327
+ options = {
328
+ instance_type: 'm3.medium',
329
+ image_id: WORKER_AMI
330
+ }
331
+
332
+ aws2.create_workers(1, options)
333
+ aws2.save_cluster_info 'server_data.json'
334
+
335
+ expect(File.exist?('server_data.json')).to eq true
336
+ # check if file exists
337
+
338
+ h = aws2.cluster_info # to make sure that the settings are correct
339
+ expect(h[:server][:worker_private_key_file_name]).to match /.*ec2_worker_key.pem/
340
+ expect(h[:workers].size).to eq 1
341
+ end
342
+
343
+ after :all do
344
+ @aws.terminate
345
+ end
346
+ end
293
347
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: openstudio-aws
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0.alpha2
4
+ version: 0.4.0.alpha3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nicholas Long
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-06-19 00:00:00.000000000 Z
11
+ date: 2015-07-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: net-scp