openstudio-aws 0.4.0.pre1 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -1
- data/.travis.yml +1 -2
- data/CHANGELOG.md +11 -12
- data/Gemfile +1 -1
- data/lib/openstudio/aws/aws.rb +19 -1
- data/lib/openstudio/aws/config.rb +35 -16
- data/lib/openstudio/aws/version.rb +1 -1
- data/lib/openstudio/lib/ami_list.rb +6 -4
- data/lib/openstudio/lib/ami_stable_version.json +5 -0
- data/lib/openstudio/lib/openstudio_aws_instance.rb +3 -3
- data/lib/openstudio/lib/openstudio_aws_wrapper.rb +37 -66
- data/lib/openstudio/lib/server_script.sh.template +19 -1
- data/lib/openstudio/lib/worker_script.sh.template +17 -8
- data/openstudio-aws.gemspec +1 -2
- data/spec/aws_instances/aws_spec_api.rb +46 -1
- data/spec/openstudio-aws/ami_list_spec.rb +1 -1
- data/spec/openstudio-aws/aws_wrapper_spec.rb +5 -6
- data/spec/openstudio-aws/config_spec.rb +44 -0
- metadata +4 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8b9a12cd70bc592eb64710b398e0dd40bf3cdcd6
|
4
|
+
data.tar.gz: 5510348a79a4a5d21fb1ca2b264bc750c7868c62
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 86d37f406f4bb02abd473be6a6b58e5f5ae29e676cb6a87e06723ced3664170844d1817c9081aa9429e3149b7d624a4ff61fe8a300124246bd35224493f19d81
|
7
|
+
data.tar.gz: 573698fb2edfc82c380d17fb2a9b09f21c47fef6c25cebe0ecb260ab1f1f631eecf9ba9ba5ba71fa50c7033ff39bce0e88b0094356973c94b839230f0dae371f
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,23 +1,14 @@
|
|
1
1
|
OpenStudio AWS Gem Change Log
|
2
2
|
==================================
|
3
3
|
|
4
|
-
Version 0.4.0
|
4
|
+
Version 0.4.0
|
5
5
|
-------------
|
6
6
|
* When listing the AMI, allow future versions of OpenStudio to return the latest stable version
|
7
|
-
|
8
|
-
Version 0.4.0.alpha3
|
9
|
-
-------------
|
10
|
-
* Load the key name and security groups from the AWS instance information.
|
7
|
+
* Load the key name and security groups from the AWS instance information.
|
11
8
|
* Add method on Aws to get the group_uuid
|
12
|
-
|
13
|
-
Version 0.4.0.alpha2
|
14
|
-
-------------
|
15
9
|
* Load worker keys from disk (if they exist) when constructing the OpenStudioAwsWrapper class
|
16
10
|
* Have `total_instances_count` return the region and first availability zone
|
17
11
|
* Add `describe_all_instances`
|
18
|
-
|
19
|
-
Version 0.4.0.alpha1
|
20
|
-
-------------
|
21
12
|
* Add a stable JSON file that can be used to flag which versions of the server are stable (used by OpenStudio PAT).
|
22
13
|
* Remove all puts and replace with logger. This is required because OpenStudio PAT reads the result from the command line.
|
23
14
|
* Add the method `describe_availability_zones` to the root AWS class
|
@@ -26,7 +17,15 @@ Version 0.4.0.alpha1
|
|
26
17
|
* Add method to `delete_key_pair`
|
27
18
|
* Add launch time to the server data struct
|
28
19
|
* Add cloud watch class to calculate the cost
|
29
|
-
* Add save_directory to override the default path to save private keys and server configuration files
|
20
|
+
* Add save_directory to override the default path to save private keys and server configuration files
|
21
|
+
* Remove old AMIs in the AMI List (versions with 0.0.x)
|
22
|
+
* Place previous stable AMI version in the list for OpenStudio
|
23
|
+
* Remove support for Ruby 1.9. Add support for Ruby 2.1.
|
24
|
+
|
25
|
+
Version 0.3.2
|
26
|
+
-------------
|
27
|
+
* Prefer use of the access and secret key in the environment variables if defined
|
28
|
+
* Support i2 instance ephemeral storage. These instances will take a bit longer to startup because the volumes are not yet created.
|
30
29
|
|
31
30
|
Version 0.3.1
|
32
31
|
-------------
|
data/Gemfile
CHANGED
data/lib/openstudio/aws/aws.rb
CHANGED
@@ -307,6 +307,13 @@ module OpenStudio
|
|
307
307
|
@os_cloudwatch.estimated_charges
|
308
308
|
end
|
309
309
|
|
310
|
+
# Stop the entire cluster
|
311
|
+
def stop
|
312
|
+
puts "Stoping any instance with group ID: #{@os_aws.group_uuid}"
|
313
|
+
|
314
|
+
stop_instances_by_group_id(@os_aws.group_uuid)
|
315
|
+
end
|
316
|
+
|
310
317
|
# Stop running instances
|
311
318
|
#
|
312
319
|
# @param group_id [String] The unique group identifier for the OpenStudio cluster.
|
@@ -320,6 +327,17 @@ module OpenStudio
|
|
320
327
|
resp
|
321
328
|
end
|
322
329
|
|
330
|
+
# Warning, it appears that this stops all the instances
|
331
|
+
def stop_instances_by_group_id(group_id)
|
332
|
+
instances = @os_aws.describe_running_instances(group_id)
|
333
|
+
ids = instances.map { |k, _| k[:instance_id] }
|
334
|
+
|
335
|
+
puts "Stoping the following instances #{ids}"
|
336
|
+
resp = []
|
337
|
+
resp = @os_aws.stop_instances(ids).to_hash unless ids.empty?
|
338
|
+
resp
|
339
|
+
end
|
340
|
+
|
323
341
|
# @params(ids): array of instance ids
|
324
342
|
def terminate_instances(ids)
|
325
343
|
logger.info "Terminating the following instances #{ids}"
|
@@ -328,7 +346,7 @@ module OpenStudio
|
|
328
346
|
resp
|
329
347
|
end
|
330
348
|
|
331
|
-
# Warning,
|
349
|
+
# Warning, it appears that this terminates all the instances
|
332
350
|
def terminate_instances_by_group_id(group_id)
|
333
351
|
fail 'Group ID not defined' unless group_id
|
334
352
|
|
@@ -1,38 +1,57 @@
|
|
1
1
|
module OpenStudio
|
2
2
|
module Aws
|
3
3
|
class Config
|
4
|
+
include Logging
|
5
|
+
|
4
6
|
attr_accessor :access_key
|
5
7
|
attr_accessor :secret_key
|
6
8
|
|
7
9
|
def initialize(yml_config_file = nil)
|
8
|
-
|
9
|
-
@
|
10
|
+
# If the AWS keys are set in the env variable and the yml_config_file is nil, then use those keys
|
11
|
+
@access_key = ENV['AWS_ACCESS_KEY_ID'] if ENV['AWS_ACCESS_KEY_ID']
|
12
|
+
@secret_key = ENV['AWS_SECRET_ACCESS_KEY'] if ENV['AWS_SECRET_ACCESS_KEY']
|
13
|
+
|
14
|
+
if @access_key && @secret_key && yml_config_file.nil?
|
15
|
+
logger.info 'Using AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY from environment variables'
|
16
|
+
else
|
17
|
+
# Otherwise read the file
|
18
|
+
logger.info 'Reading AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY from aws config file'
|
19
|
+
|
20
|
+
@yml_config_file = yml_config_file
|
21
|
+
@config = nil
|
22
|
+
|
23
|
+
@yml_config_file = File.join(File.expand_path('~'), 'aws_config.yml') if @yml_config_file.nil?
|
10
24
|
|
11
|
-
if @yml_config_file.nil?
|
12
|
-
@yml_config_file = File.join(File.expand_path('~'), 'aws_config.yml')
|
13
25
|
unless File.exist?(@yml_config_file)
|
14
26
|
write_config_file
|
15
|
-
fail "
|
27
|
+
fail "Config file not found. A template has been added, please edit and save: #{@yml_config_file}"
|
16
28
|
exit 1
|
17
29
|
end
|
18
|
-
end
|
19
30
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
31
|
+
begin
|
32
|
+
@config = YAML.load(File.read(@yml_config_file))
|
33
|
+
|
34
|
+
# always convert to symbolized hash
|
35
|
+
@config = @config.inject({}) { |a, (k, v)| a[k.to_sym] = v; a }
|
36
|
+
|
37
|
+
@access_key = @config[:access_key_id]
|
38
|
+
@secret_key = @config[:secret_access_key]
|
39
|
+
rescue
|
40
|
+
raise "Couldn't read config file #{@yml_config_file}. Delete file then recreate by rerunning script"
|
41
|
+
end
|
26
42
|
end
|
27
43
|
end
|
28
44
|
|
29
45
|
private
|
30
46
|
|
31
47
|
def write_config_file
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
48
|
+
# create the file
|
49
|
+
data = {
|
50
|
+
access_key_id: 'YOUR_ACCESS_KEY_ID',
|
51
|
+
secret_access_key: 'YOUR_SECRET_ACCESS_KEY'
|
52
|
+
}
|
53
|
+
|
54
|
+
File.open(@yml_config_file, 'w') { |f| f << data.to_yaml }
|
36
55
|
end
|
37
56
|
end
|
38
57
|
end
|
@@ -1,6 +1,5 @@
|
|
1
|
-
# NOTE: Do not modify this file as it is copied over. Modify the source file and rerun rake import_files
|
2
1
|
######################################################################
|
3
|
-
# Copyright (c) 2008-
|
2
|
+
# Copyright (c) 2008-2015, Alliance for Sustainable Energy.
|
4
3
|
# All rights reserved.
|
5
4
|
#
|
6
5
|
# This library is free software; you can redistribute it and/or
|
@@ -119,10 +118,11 @@ class OpenStudioAmis
|
|
119
118
|
stable = nil
|
120
119
|
if json[:openstudio][@options[:openstudio_version].to_sym]
|
121
120
|
stable = json[:openstudio][@options[:openstudio_version].to_sym][:stable]
|
121
|
+
logger.info "The stable version in the JSON is #{stable}"
|
122
122
|
end
|
123
123
|
|
124
124
|
if stable
|
125
|
-
value = json[:
|
125
|
+
value = json[:openstudio_server][stable.to_sym]
|
126
126
|
amis = value[:amis]
|
127
127
|
else
|
128
128
|
logger.info "Could not find a stable version for OpenStudio version #{@options[:openstudio_version]}. "\
|
@@ -130,12 +130,14 @@ class OpenStudioAmis
|
|
130
130
|
|
131
131
|
json[:openstudio].each do |os_version, values|
|
132
132
|
next if os_version == :default
|
133
|
+
|
133
134
|
if values.key? :stable
|
134
135
|
# don't check versions newer than what we are requesting
|
135
136
|
next if os_version.to_s.to_version > @options[:openstudio_version].to_s.to_version
|
137
|
+
|
136
138
|
stable = json[:openstudio][os_version][:stable]
|
137
139
|
logger.info "Found a stable version for OpenStudio version #{os_version} with OpenStudio Server version #{stable}"
|
138
|
-
value =
|
140
|
+
value = json[:openstudio_server][stable.to_sym]
|
139
141
|
amis = value[:amis]
|
140
142
|
|
141
143
|
break
|
@@ -1,5 +1,5 @@
|
|
1
1
|
######################################################################
|
2
|
-
# Copyright (c) 2008-
|
2
|
+
# Copyright (c) 2008-2015, Alliance for Sustainable Energy.
|
3
3
|
# All rights reserved.
|
4
4
|
#
|
5
5
|
# This library is free software; you can redistribute it and/or
|
@@ -35,7 +35,7 @@ class OpenStudioAwsInstance
|
|
35
35
|
@key_pair_name = key_pair_name
|
36
36
|
@security_groups = security_groups
|
37
37
|
@group_uuid = group_uuid.to_s
|
38
|
-
@init_timestamp = Time.now
|
38
|
+
@init_timestamp = Time.now # This is the timestamp and is typically just tracked for the server
|
39
39
|
@private_key = private_key
|
40
40
|
@private_key_file_name = private_key_file_name
|
41
41
|
@proxy = proxy
|
@@ -390,7 +390,7 @@ class OpenStudioAwsInstance
|
|
390
390
|
rescue SystemCallError, Timeout::Error => e
|
391
391
|
# port 22 might not be available immediately after the instance finishes launching
|
392
392
|
sleep 10
|
393
|
-
logger.info('Timeout. Perhaps there is a communication error to EC2? Will try again')
|
393
|
+
logger.info('Timeout. Perhaps there is a communication error to EC2? Will try again in 10 seconds')
|
394
394
|
retry
|
395
395
|
end
|
396
396
|
|
@@ -17,24 +17,6 @@
|
|
17
17
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
18
18
|
######################################################################
|
19
19
|
|
20
|
-
######################################################################
|
21
|
-
# == Synopsis
|
22
|
-
#
|
23
|
-
# Uses the aws-sdk gem to communicate with AWS
|
24
|
-
#
|
25
|
-
# == Usage
|
26
|
-
#
|
27
|
-
# ruby aws.rb access_key secret_key us-east-1 EC2 launch_server "{\"instance_type\":\"t1.micro\"}"
|
28
|
-
#
|
29
|
-
# ARGV[0] - Access Key
|
30
|
-
# ARGV[1] - Secret Key
|
31
|
-
# ARGV[2] - Region
|
32
|
-
# ARGV[3] - Service (e.g. "EC2" or "CloudWatch")
|
33
|
-
# ARGV[4] - Command (e.g. "launch_server")
|
34
|
-
# ARGV[5] - Optional json with parameters associated with command
|
35
|
-
#
|
36
|
-
######################################################################
|
37
|
-
|
38
20
|
require_relative 'openstudio_aws_logger'
|
39
21
|
|
40
22
|
class OpenStudioAwsWrapper
|
@@ -53,8 +35,7 @@ class OpenStudioAwsWrapper
|
|
53
35
|
VALID_OPTIONS = [:proxy, :credentials]
|
54
36
|
|
55
37
|
def initialize(options = {}, group_uuid = nil)
|
56
|
-
@group_uuid = group_uuid || (SecureRandom.uuid).
|
57
|
-
logger.info "GroupUUID is #{@group_uuid}"
|
38
|
+
@group_uuid = group_uuid || (SecureRandom.uuid).delete('-')
|
58
39
|
|
59
40
|
@security_groups = []
|
60
41
|
@key_pair_name = nil
|
@@ -218,22 +199,17 @@ class OpenStudioAwsWrapper
|
|
218
199
|
instance_data
|
219
200
|
end
|
220
201
|
|
221
|
-
|
202
|
+
# Describe the list of AMIs adn return the hash.
|
203
|
+
# @param [Array] image_ids: List of image ids to find. If empty, then will find all images.
|
204
|
+
# @param [Boolean] owned_by_me: Find only the images owned by the current user?
|
205
|
+
# @return [Hash]
|
206
|
+
def describe_amis(image_ids = [], owned_by_me = true)
|
222
207
|
resp = nil
|
223
208
|
|
224
|
-
# TODO: test the filter. i don't think that it is exposed in the AWS gem?
|
225
209
|
if owned_by_me
|
226
|
-
|
227
|
-
resp = @aws.describe_images(owners: [:self], filter: filter).data
|
228
|
-
else
|
229
|
-
resp = @aws.describe_images(owners: [:self]).data
|
230
|
-
end
|
210
|
+
resp = @aws.describe_images(owners: [:self]).data
|
231
211
|
else
|
232
|
-
|
233
|
-
resp = @aws.describe_images(filter: filter).data
|
234
|
-
else
|
235
|
-
resp = @aws.describe_images(image_ids: image_ids).data
|
236
|
-
end
|
212
|
+
resp = @aws.describe_images(image_ids: image_ids).data
|
237
213
|
end
|
238
214
|
|
239
215
|
resp = resp.to_hash
|
@@ -242,11 +218,15 @@ class OpenStudioAwsWrapper
|
|
242
218
|
resp[:images].each do |image|
|
243
219
|
image[:tags_hash] = {}
|
244
220
|
image[:tags_hash][:tags] = []
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
221
|
+
|
222
|
+
# If the image is being created then its tags may be empty
|
223
|
+
if image[:tags]
|
224
|
+
image[:tags].each do |tag|
|
225
|
+
if tag[:value]
|
226
|
+
image[:tags_hash][tag[:key].to_sym] = tag[:value]
|
227
|
+
else
|
228
|
+
image[:tags_hash][:tags] << tag[:key]
|
229
|
+
end
|
250
230
|
end
|
251
231
|
end
|
252
232
|
end
|
@@ -254,6 +234,8 @@ class OpenStudioAwsWrapper
|
|
254
234
|
resp
|
255
235
|
end
|
256
236
|
|
237
|
+
# Stop specific instances based on the instance_ids
|
238
|
+
# @param [Array] ids: Array of ids to stop
|
257
239
|
def stop_instances(ids)
|
258
240
|
resp = @aws.stop_instances(
|
259
241
|
instance_ids: ids,
|
@@ -549,8 +531,6 @@ class OpenStudioAwsWrapper
|
|
549
531
|
|
550
532
|
# now grab the good keys - they should be sorted newest to older... so go backwards
|
551
533
|
amis[:openstudio_server].keys.reverse_each do |key|
|
552
|
-
next if amis[:openstudio_server][key][:deprecate]
|
553
|
-
|
554
534
|
a = amis[:openstudio_server][key]
|
555
535
|
# this will override any of the old ami/os version
|
556
536
|
version1[a[:openstudio_version].to_sym] = a[:amis]
|
@@ -568,20 +548,33 @@ class OpenStudioAwsWrapper
|
|
568
548
|
# don't need to transform anything right now, only flag which ones are stable version so that the uploaded ami JSON has the
|
569
549
|
# stable server for OpenStudio PAT to use.
|
570
550
|
stable = JSON.parse File.read(File.join(File.dirname(__FILE__), 'ami_stable_version.json')), symbolize_names: true
|
571
|
-
# go through and tag the versions of the openstudio instances that are stable
|
572
551
|
|
552
|
+
# go through and tag the versions of the openstudio instances that are stable,
|
573
553
|
stable[:openstudio].each do |k, v|
|
574
554
|
if amis[:openstudio][k.to_s] && amis[:openstudio][k.to_s][v.to_sym]
|
575
555
|
amis[:openstudio][k.to_s][:stable] = v
|
576
556
|
end
|
577
557
|
end
|
578
558
|
|
559
|
+
# I'm not sure what the below code is trying to accomplish. Are we even using the default?
|
579
560
|
k, v = stable[:openstudio].first
|
580
561
|
if k && v
|
581
562
|
if amis[:openstudio][k.to_s]
|
582
563
|
amis[:openstudio][:default] = v
|
583
564
|
end
|
584
565
|
end
|
566
|
+
|
567
|
+
# now go through and if the OpenStudio version does not have a stable key, then assign it the most recent
|
568
|
+
# stable AMI. This allows for easy testing so a new version of OpenStudio can use an existing AMI.
|
569
|
+
stable[:openstudio].each do |stable_openstudio, stable_server|
|
570
|
+
amis[:openstudio].each do |k, v|
|
571
|
+
next if k == :default
|
572
|
+
|
573
|
+
if k.to_s.to_version > stable_openstudio.to_s.to_version && v[:stable].nil?
|
574
|
+
amis[:openstudio][k.to_s][:stable] = stable_server.to_s
|
575
|
+
end
|
576
|
+
end
|
577
|
+
end
|
585
578
|
end
|
586
579
|
|
587
580
|
amis
|
@@ -606,7 +599,8 @@ class OpenStudioAwsWrapper
|
|
606
599
|
h
|
607
600
|
end
|
608
601
|
|
609
|
-
# take the base version and increment the patch until
|
602
|
+
# take the base version and increment the patch until.
|
603
|
+
# TODO: DEPRECATE
|
610
604
|
def get_next_version(base, list_of_svs)
|
611
605
|
b = base.to_version
|
612
606
|
|
@@ -634,8 +628,8 @@ class OpenStudioAwsWrapper
|
|
634
628
|
sv = ami[:tags_hash][:openstudio_server_version]
|
635
629
|
|
636
630
|
if sv.nil? || sv == ''
|
637
|
-
logger.info 'found nil
|
638
|
-
|
631
|
+
logger.info 'found nil Server Version, ignoring'
|
632
|
+
next
|
639
633
|
end
|
640
634
|
list_of_svs << sv
|
641
635
|
|
@@ -646,11 +640,9 @@ class OpenStudioAwsWrapper
|
|
646
640
|
a[:amis] = {} unless a[:amis]
|
647
641
|
|
648
642
|
# fill in data (this will override data currently)
|
649
|
-
a[:deprecate] = true if sv.to_version.satisfies('0.0.*')
|
650
643
|
a[:openstudio_version] = ami[:tags_hash][:openstudio_version] if ami[:tags_hash][:openstudio_version]
|
651
644
|
a[:openstudio_version_sha] = ami[:tags_hash][:openstudio_version_sha] if ami[:tags_hash][:openstudio_version_sha]
|
652
645
|
a[:user_uuid] = ami[:tags_hash][:user_uuid] if ami[:tags_hash][:user_uuid]
|
653
|
-
a[:deprecate] = ami[:tags_hash][:deprecate] if ami[:tags_hash][:deprecate]
|
654
646
|
a[:created_on] = ami[:tags_hash][:created_on] if ami[:tags_hash][:created_on]
|
655
647
|
a[:openstudio_server_version] = sv.to_s
|
656
648
|
if ami[:tags_hash][:tested]
|
@@ -687,29 +679,8 @@ class OpenStudioAwsWrapper
|
|
687
679
|
end
|
688
680
|
end
|
689
681
|
|
690
|
-
# merge in the existing AMIs the existing amis into the 'unknown category, but don't flag them as 'deprecate'
|
691
|
-
existing.keys.each do |ami_key|
|
692
|
-
next if ami_key == 'default'.to_sym # ignore default
|
693
|
-
|
694
|
-
# get next version
|
695
|
-
next_version = get_next_version('0.0.1', list_of_svs)
|
696
|
-
list_of_svs << next_version
|
697
|
-
|
698
|
-
amis[:openstudio_server][next_version.to_sym] ||= {}
|
699
|
-
a = amis[:openstudio_server][next_version.to_sym]
|
700
|
-
a[:amis] = {} unless a[:amis]
|
701
|
-
|
702
|
-
a[:openstudio_version] = ami_key
|
703
|
-
a[:amis][:server] = existing[ami_key][:server]
|
704
|
-
a[:amis][:worker] = existing[ami_key][:worker]
|
705
|
-
a[:amis][:cc2worker] = existing[ami_key][:cc2worker]
|
706
|
-
a[:openstudio_server_version] = next_version.to_s
|
707
|
-
end
|
708
|
-
|
709
682
|
# flip these around for openstudio server section
|
710
683
|
amis[:openstudio_server].keys.each do |key|
|
711
|
-
next if key.to_s.to_version.satisfies('0.0.*')
|
712
|
-
|
713
684
|
a = amis[:openstudio_server][key]
|
714
685
|
ov = a[:openstudio_version]
|
715
686
|
|
@@ -44,12 +44,28 @@ chmod 775 /usr/local/bin/ec2-metadata
|
|
44
44
|
mkdir -p /etc/openstudio-server
|
45
45
|
ec2-metadata -a -i -t -h -o -z -p -v > /etc/openstudio-server/instance.yml
|
46
46
|
|
47
|
+
# make sure supervisor is running
|
48
|
+
sudo service supervisor start
|
49
|
+
|
47
50
|
# stop the various services that use mongo
|
48
51
|
service delayed_job stop
|
52
|
+
supervisorctl stop delayed_job
|
49
53
|
service apache2 stop
|
50
54
|
service mongodb stop
|
51
55
|
service mongod stop
|
52
56
|
|
57
|
+
# make sure the the /mnt directory exists if i2 instances.
|
58
|
+
# For now this assumes that the volume is xvdb. In the future this
|
59
|
+
# should be dynamic
|
60
|
+
if ec2-metadata --instance-type | grep -q 'i2.'; then
|
61
|
+
mkfs.ext4 /dev/xvdb
|
62
|
+
mkdir -p /mnt
|
63
|
+
mount -t ext4 /dev/xvdb /mnt
|
64
|
+
|
65
|
+
echo "/dev/xvdb /mnt auto noatime 0 0" | sudo tee -a /etc/fstab
|
66
|
+
mount -a
|
67
|
+
fi
|
68
|
+
|
53
69
|
# remove mongo db & add it back
|
54
70
|
mkdir -p /mnt/mongodb/data
|
55
71
|
chown mongodb:nogroup /mnt/mongodb/data
|
@@ -118,9 +134,11 @@ find /mnt/openstudio -type f -print0 | xargs -0 chmod 664
|
|
118
134
|
|
119
135
|
# restart rserve
|
120
136
|
service Rserve restart
|
137
|
+
supervisorctl restart Rserve
|
121
138
|
|
122
|
-
#
|
139
|
+
# start delayed jobs
|
123
140
|
service delayed_job start
|
141
|
+
supervisorctl start delayed_job
|
124
142
|
|
125
143
|
#file flag the user_data has completed
|
126
144
|
cat /dev/null > /home/ubuntu/user_data_done
|
@@ -35,6 +35,18 @@ chmod 775 /usr/local/bin/ec2-metadata
|
|
35
35
|
mkdir -p /etc/openstudio-server
|
36
36
|
ec2-metadata -a -i -t -h -o -z -p -v > /etc/openstudio-server/instance.yml
|
37
37
|
|
38
|
+
# make sure the the /mnt directory exists if i2 instances.
|
39
|
+
# For now this assumes that the volume is xvdb. In the future this
|
40
|
+
# should be dynamic
|
41
|
+
if ec2-metadata --instance-type | grep -q 'i2.'; then
|
42
|
+
mkfs.ext4 /dev/xvdb
|
43
|
+
mkdir -p /mnt
|
44
|
+
mount -t ext4 /dev/xvdb /mnt
|
45
|
+
|
46
|
+
echo "/dev/xvdb /mnt auto noatime 0 0" | sudo tee -a /etc/fstab
|
47
|
+
mount -a
|
48
|
+
fi
|
49
|
+
|
38
50
|
## Worker Data Configuration -- On Vagrant this is a separate file
|
39
51
|
|
40
52
|
rm -f /tmp/snow.log
|
@@ -63,14 +75,11 @@ find /mnt/openstudio -type f -print0 | xargs -0 chmod 664
|
|
63
75
|
|
64
76
|
## End Worker Data Configuration
|
65
77
|
|
66
|
-
#
|
67
|
-
|
68
|
-
|
69
|
-
#for
|
70
|
-
|
71
|
-
# cut -s -d, -f2- | tr ',' '\n' | sort -un); do
|
72
|
-
# echo 0 > /sys/devices/system/cpu/cpu$cpunum/online
|
73
|
-
#done
|
78
|
+
# make sure supervisor is running
|
79
|
+
sudo service supervisor start
|
80
|
+
|
81
|
+
# Rserve is now on the worker nodes for use by measures
|
82
|
+
supervisorctl restart Rserve
|
74
83
|
|
75
84
|
#file flag the user_data has completed
|
76
85
|
cat /dev/null > /home/ubuntu/user_data_done
|
data/openstudio-aws.gemspec
CHANGED
@@ -14,7 +14,7 @@ Gem::Specification.new do |s|
|
|
14
14
|
s.description = 'Custom classes for configuring clusters for OpenStudio & EnergyPlus analyses'
|
15
15
|
s.license = 'LGPL'
|
16
16
|
|
17
|
-
s.required_ruby_version = '>=
|
17
|
+
s.required_ruby_version = '>= 2.0.0'
|
18
18
|
s.required_rubygems_version = '>= 1.3.6'
|
19
19
|
|
20
20
|
s.add_dependency 'net-scp', '~> 1.1'
|
@@ -22,7 +22,6 @@ Gem::Specification.new do |s|
|
|
22
22
|
s.add_dependency 'semantic', '~> 1.4'
|
23
23
|
s.add_dependency 'sshkey', '~> 1.7'
|
24
24
|
|
25
|
-
s.add_development_dependency 'bundler', '~> 1.7'
|
26
25
|
s.add_development_dependency 'rake', '~> 10.4'
|
27
26
|
|
28
27
|
s.files = `git ls-files -z`.split("\x0")
|
@@ -252,7 +252,11 @@ describe OpenStudio::Aws::Aws do
|
|
252
252
|
begin
|
253
253
|
options = {
|
254
254
|
instance_type: 'm3.medium',
|
255
|
-
image_id: SERVER_AMI
|
255
|
+
image_id: SERVER_AMI,
|
256
|
+
tags: [
|
257
|
+
'ci_tests=true',
|
258
|
+
'ServerOnly=true'
|
259
|
+
]
|
256
260
|
}
|
257
261
|
|
258
262
|
expect(@aws.save_directory).to eq File.join(File.expand_path('.'), 'spec/output/save_path')
|
@@ -344,4 +348,45 @@ describe OpenStudio::Aws::Aws do
|
|
344
348
|
@aws.terminate
|
345
349
|
end
|
346
350
|
end
|
351
|
+
|
352
|
+
context 'i2-instances' do
|
353
|
+
before :all do
|
354
|
+
@config = OpenStudio::Aws::Config.new
|
355
|
+
@aws = OpenStudio::Aws::Aws.new
|
356
|
+
|
357
|
+
@group_id = nil
|
358
|
+
end
|
359
|
+
|
360
|
+
it 'should create an i2 instance and mount the storage' do
|
361
|
+
begin
|
362
|
+
options = {
|
363
|
+
instance_type: 'i2.xlarge',
|
364
|
+
image_id: SERVER_AMI,
|
365
|
+
tags: [
|
366
|
+
'ci_tests=true',
|
367
|
+
'ServerOnly=true'
|
368
|
+
]
|
369
|
+
}
|
370
|
+
|
371
|
+
expect { @aws.create_workers(0) }.to raise_error "Can't create workers without a server instance running"
|
372
|
+
|
373
|
+
test_pem_file = 'ec2_server_key.pem'
|
374
|
+
FileUtils.rm_f test_pem_file if File.exist? test_pem_file
|
375
|
+
FileUtils.rm_f 'server_data.json' if File.exist? 'server_data.json'
|
376
|
+
|
377
|
+
@aws.create_server(options)
|
378
|
+
|
379
|
+
# Still have to call "create workers" or the configuration won't happen.
|
380
|
+
@aws.create_workers(0, options)
|
381
|
+
|
382
|
+
h = @aws.os_aws.server.to_os_hash
|
383
|
+
|
384
|
+
shell = @aws.server.shell_command('df -h | grep /dev/xvdb.*/mnt')
|
385
|
+
expect(shell).not_to be_nil
|
386
|
+
expect(shell).to eq /\/dev\/xvdb.*\/mnt/
|
387
|
+
ensure
|
388
|
+
@aws.terminate_instances_by_group_id(h[:group_id])
|
389
|
+
end
|
390
|
+
end
|
391
|
+
end
|
347
392
|
end
|
@@ -43,7 +43,7 @@ describe OpenStudioAmis do
|
|
43
43
|
end
|
44
44
|
|
45
45
|
context 'version 2' do
|
46
|
-
it 'should return openstudio version 1.7.1 stable
|
46
|
+
it 'should return openstudio version 1.7.1 when stable is passed to 1.7.5' do
|
47
47
|
a = OpenStudioAmis.new(2, openstudio_version: '1.7.5', stable: true)
|
48
48
|
|
49
49
|
amis = a.get_amis
|
@@ -49,12 +49,12 @@ describe OpenStudioAwsWrapper do
|
|
49
49
|
|
50
50
|
context 'create new ami json' do
|
51
51
|
it 'should describe existing AMIs' do
|
52
|
-
resp = @aws.os_aws.describe_amis
|
53
|
-
expect(resp[:images].length).to be >=
|
52
|
+
resp = @aws.os_aws.describe_amis
|
53
|
+
expect(resp[:images].length).to be >= 10
|
54
54
|
end
|
55
55
|
|
56
56
|
it 'should describe a specific image' do
|
57
|
-
resp = @aws.os_aws.describe_amis(
|
57
|
+
resp = @aws.os_aws.describe_amis(['ami-39bb8750'], false)
|
58
58
|
expect(resp[:images].first[:image_id]).to eq('ami-39bb8750')
|
59
59
|
expect(resp[:images].first[:tags_hash][:user_uuid]).to eq('jenkins-139LADFJ178')
|
60
60
|
expect(resp[:images].first[:tags_hash][:openstudio_server_version]).to eq('1.3.1')
|
@@ -62,10 +62,10 @@ describe OpenStudioAwsWrapper do
|
|
62
62
|
end
|
63
63
|
|
64
64
|
context 'version 1' do
|
65
|
-
it 'should create a new json' do
|
65
|
+
it 'should create a new json and return the right server versions' do
|
66
66
|
resp = @aws.os_aws.create_new_ami_json(1)
|
67
|
-
expect(resp['1.1.3'.to_sym][:server]).to eq('ami-fb301292')
|
68
67
|
expect(resp['1.2.1'.to_sym][:server]).to eq('ami-89744be0')
|
68
|
+
expect(resp['1.9.0'.to_sym][:server]).to eq('ami-f3611996')
|
69
69
|
expect(resp['default'.to_sym][:server]).to_not eq('ami-89744be0')
|
70
70
|
end
|
71
71
|
end
|
@@ -103,7 +103,6 @@ describe OpenStudioAwsWrapper do
|
|
103
103
|
|
104
104
|
it 'should create security group' do
|
105
105
|
sg = @aws.os_aws.create_or_retrieve_default_security_group
|
106
|
-
pp sg
|
107
106
|
expect(sg).to_not be nil
|
108
107
|
end
|
109
108
|
end
|
@@ -6,5 +6,49 @@ describe OpenStudio::Aws::Config do
|
|
6
6
|
@config = OpenStudio::Aws::Config.new
|
7
7
|
expect(@config).not_to be_nil
|
8
8
|
end
|
9
|
+
|
10
|
+
it 'should create a new file' do
|
11
|
+
local_file = 'test.config'
|
12
|
+
File.delete local_file if File.exist? local_file
|
13
|
+
|
14
|
+
expect { OpenStudio::Aws::Config.new local_file }.to raise_error /Config file not found. A template has been added, please edit and save: test.config/
|
15
|
+
expect(File.exist?(local_file)).to eq true
|
16
|
+
|
17
|
+
# read the file and make sure that the template is there
|
18
|
+
config = YAML.load(File.read(local_file))
|
19
|
+
expect(config[:access_key_id]).to eq 'YOUR_ACCESS_KEY_ID'
|
20
|
+
expect(config[:secret_access_key]).to eq 'YOUR_SECRET_ACCESS_KEY'
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'should read old format' do
|
24
|
+
# make sure that we can read the old format which has non-symoblized keys
|
25
|
+
local_file = 'test_custom_old.config'
|
26
|
+
|
27
|
+
data = {
|
28
|
+
'access_key_id' => 'abcd',
|
29
|
+
'secret_access_key' => 'efgh'
|
30
|
+
}
|
31
|
+
|
32
|
+
File.open(local_file, 'w') { |f| f << data.to_yaml }
|
33
|
+
config = OpenStudio::Aws::Config.new local_file
|
34
|
+
expect(config.access_key).to eq 'abcd'
|
35
|
+
expect(config.secret_key).to eq 'efgh'
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'should read a custom file' do
|
39
|
+
local_file = 'test_custom.config'
|
40
|
+
|
41
|
+
# create the file
|
42
|
+
data = {
|
43
|
+
access_key_id: 'random_key',
|
44
|
+
secret_access_key: 'random_secret_key'
|
45
|
+
}
|
46
|
+
|
47
|
+
File.open(local_file, 'w') { |f| f << data.to_yaml }
|
48
|
+
|
49
|
+
config = OpenStudio::Aws::Config.new local_file
|
50
|
+
expect(config.access_key).to eq 'random_key'
|
51
|
+
expect(config.secret_key).to eq 'random_secret_key'
|
52
|
+
end
|
9
53
|
end
|
10
54
|
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
|
4
|
+
version: 0.4.0
|
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-
|
11
|
+
date: 2015-11-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: net-scp
|
@@ -66,20 +66,6 @@ dependencies:
|
|
66
66
|
- - ~>
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '1.7'
|
69
|
-
- !ruby/object:Gem::Dependency
|
70
|
-
name: bundler
|
71
|
-
requirement: !ruby/object:Gem::Requirement
|
72
|
-
requirements:
|
73
|
-
- - ~>
|
74
|
-
- !ruby/object:Gem::Version
|
75
|
-
version: '1.7'
|
76
|
-
type: :development
|
77
|
-
prerelease: false
|
78
|
-
version_requirements: !ruby/object:Gem::Requirement
|
79
|
-
requirements:
|
80
|
-
- - ~>
|
81
|
-
- !ruby/object:Gem::Version
|
82
|
-
version: '1.7'
|
83
69
|
- !ruby/object:Gem::Dependency
|
84
70
|
name: rake
|
85
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -146,7 +132,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
146
132
|
requirements:
|
147
133
|
- - '>='
|
148
134
|
- !ruby/object:Gem::Version
|
149
|
-
version:
|
135
|
+
version: 2.0.0
|
150
136
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
151
137
|
requirements:
|
152
138
|
- - '>='
|
@@ -154,7 +140,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
154
140
|
version: 1.3.6
|
155
141
|
requirements: []
|
156
142
|
rubyforge_project:
|
157
|
-
rubygems_version: 2.
|
143
|
+
rubygems_version: 2.0.14.1
|
158
144
|
signing_key:
|
159
145
|
specification_version: 4
|
160
146
|
summary: Start AWS EC2 instances for running distributed OpenStudio-based analyses
|