openstudio-aws 0.3.2 → 0.4.0.alpha1

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: 58446e6c6b933ab0dd7e9b37662135ed69f49b30
4
- data.tar.gz: 5d3a66b33ae75198773aa12370045ef584e8da1e
3
+ metadata.gz: 0caae029f8b89a624ac2eae705dd9116f6fb73d6
4
+ data.tar.gz: 9027677347681dfda91f3b57bdf4266ec4da5822
5
5
  SHA512:
6
- metadata.gz: 48ab27614c9e80e4dd8ffb0edf8afbc1ce9f3017dd8c94f56eb33e531136c263fb0815638bc9c66ce5e2c78e40dfb19d21481518cc4a66d36ec024816870256f
7
- data.tar.gz: 5668f2229c8e525d22f64ae1796b512941dc8cb9f6680759ab7c0129b52f6d707cbf347363d1d4cf4381a218da5b4871703b6694e4a66d8c62c1ee18d9b35584
6
+ metadata.gz: 92220c6aa21ced920173e584686c10546bc92bb2c2d5668dc911668ffd7fb5c38ea34e4c82793f329e2a0d37d19602667afb03a76c81224ac9bfb004244f815b
7
+ data.tar.gz: c8b09f832050cc296425ee4a08b1cb95fba8002dd151a794b0fab0895afdf8752b197da29e7a476148ebdb827ae6fc6bd25ce05227ebf66968b93327bd138d58
data/.gitignore CHANGED
@@ -15,6 +15,6 @@ spec/reports
15
15
  ~$*
16
16
  *.receipt
17
17
  rubocop-results.xml
18
+ spec/output
18
19
  *.pem
19
- *.pub
20
- *.config
20
+ *.pub
data/CHANGELOG.md CHANGED
@@ -1,12 +1,17 @@
1
1
  OpenStudio AWS Gem Change Log
2
2
  ==================================
3
3
 
4
- Version 0.3.2 (Unreleased)
4
+ Version 0.4.0.alpha1
5
5
  -------------
6
6
  * Add a stable JSON file that can be used to flag which versions of the server are stable (used by OpenStudio PAT).
7
+ * Remove all puts and replace with logger. This is required because OpenStudio PAT reads the result from the command line.
7
8
  * Add the method `describe_availability_zones` to the root AWS class
8
- * Prefer use of the access and secret key in the environment variables if defined
9
- * Support i2 instance ephemeral storage. These instances will take a bit longer to startup because the volumes are not yet created.
9
+ * Add the method `total_instances_count` to the root AWS class
10
+ * Add method to list status of all instances in the group
11
+ * Add method to `delete_key_pair`
12
+ * Add launch time to the server data struct
13
+ * Add cloud watch class to calculate the cost
14
+ * Add save_directory to override the default path to save private keys and server configuration files
10
15
 
11
16
  Version 0.3.1
12
17
  -------------
data/Gemfile CHANGED
@@ -3,7 +3,7 @@ source 'http://rubygems.org'
3
3
  gemspec
4
4
 
5
5
  group :test do
6
- gem 'rspec', '~> 3.3'
6
+ gem 'rspec', '~> 3.2.0'
7
7
  gem 'ci_reporter_rspec'
8
8
  gem 'rubocop', '~> 0.31'
9
9
  gem 'rubocop-checkstyle_formatter', '~> 0.2'
@@ -3,18 +3,29 @@ module OpenStudio
3
3
  module Aws
4
4
  VALID_OPTIONS = [
5
5
  :proxy, :credentials, :ami_lookup_version, :openstudio_version,
6
- :openstudio_server_version, :region, :ssl_verify_peer, :host, :url, :stable
6
+ :openstudio_server_version, :region, :ssl_verify_peer, :host, :url, :stable,
7
+ :save_directory
7
8
  ]
8
9
 
9
10
  class Aws
11
+ include Logging
12
+
10
13
  # Deprecate OS_AWS object
11
14
  attr_reader :os_aws
12
15
  attr_reader :default_amis
16
+ attr_reader :save_directory
13
17
 
14
18
  # default constructor to create the AWS class that can spin up server and worker instances.
15
19
  # options are optional with the following support:
16
20
  # credentials => {:access_key_id, :secret_access_key, :region, :ssl_verify_peer}
17
21
  # proxy => {:host => "192.168.0.1", :port => "8808", :username => "user", :password => "password"}}
22
+ # @param options [Hash]
23
+ # @option options [Boolean] :openstudio_version Version of OpenStudio in which to do the lookup for the server
24
+ # AMIs. This cannot be used in conjunction with the :openstudio_server_version.
25
+ # @option options [Boolean] :openstudio_server_version Version of OpenStudio Server in which to do the lookup for
26
+ # the server AMIs. This cannot be used in conjunction with the :openstudio_server_version
27
+ # @option options [Boolean] :stable (false) Find a stable version less than or equal to the version that is passed in the
28
+ # version field
18
29
  def initialize(options = {})
19
30
  invalid_options = options.keys - VALID_OPTIONS
20
31
  if invalid_options.any?
@@ -25,9 +36,15 @@ module OpenStudio
25
36
  defaults = {
26
37
  ami_lookup_version: 1,
27
38
  region: 'us-east-1',
28
- ssl_verify_peer: false
39
+ ssl_verify_peer: false,
40
+ save_directory: '.'
29
41
  }
30
42
  options = defaults.merge(options)
43
+ logger.info "AWS initialized with the options: #{options.except(:credentials)}"
44
+
45
+ # set the save path
46
+ @save_directory = File.expand_path options[:save_directory]
47
+ FileUtils.mkdir_p @save_directory unless Dir.exist? @save_directory
31
48
 
32
49
  # read in the config.yml file to get the secret/private key
33
50
  if !options[:credentials]
@@ -53,19 +70,11 @@ module OpenStudio
53
70
  else
54
71
  proxy_uri = "https://#{options[:proxy][:host]}:#{options[:proxy][:port]}"
55
72
  end
56
- # TODO: remove this proxy_uri and make a method to format correctly
57
73
  options[:proxy_uri] = proxy_uri
58
-
59
- # TODO: do we need to escape a couple of the argument of username and password
60
-
61
- # TODO: set some environment variables for system based proxy
62
74
  end
63
75
 
64
- # puts "Final options are: #{options.inspect}"
65
-
66
76
  @os_aws = OpenStudioAwsWrapper.new(options)
67
-
68
- @instances_filename = nil
77
+ @os_cloudwatch = OpenStudioCloudWatch.new(options)
69
78
 
70
79
  # this will grab the default version of openstudio ami versions
71
80
  # get the arugments for the AMI lookup
@@ -85,10 +94,10 @@ module OpenStudio
85
94
  #
86
95
  # end
87
96
 
88
- # command line call to create a new instance. This should be more tightly integrated with teh os-aws.rb gem
89
- def create_server(options = {}, instances_filename = 'server_data.json')
97
+ # command line call to create a new instance. This should be more tightly integrated with the os-aws.rb gem
98
+ def create_server(options = {})
90
99
  defaults = {
91
- instance_type: 'm2.xlarge',
100
+ instance_type: 'm3.xlarge',
92
101
  security_groups: [],
93
102
  image_id: @default_amis[:server],
94
103
  user_id: 'unknown_user',
@@ -129,7 +138,7 @@ module OpenStudio
129
138
  @os_aws.private_key_file_name = options[:private_key_file_name]
130
139
  else
131
140
  # Save the private key if you did not pass in an already existing key_pair_name
132
- @os_aws.save_private_key('ec2_server_key.pem')
141
+ @os_aws.save_private_key(@save_directory)
133
142
  end
134
143
 
135
144
  server_options = {
@@ -141,22 +150,30 @@ module OpenStudio
141
150
 
142
151
  # save the worker pem and public to the directory
143
152
  # presently, this will always overwrite the worker key, is that okay? Is this really needed later?
144
- @os_aws.save_worker_keys('.')
153
+ @os_aws.save_worker_keys(@save_directory)
145
154
 
146
155
  # if instance_data[:ebs_volume_id]
147
156
  # server_options[:ebs_volume_id] = instance_data[:ebs_volume_id]
148
157
  # end
149
158
 
150
159
  @os_aws.launch_server(options[:image_id], options[:instance_type], server_options)
160
+ end
151
161
 
152
- @instances_filename = instances_filename
153
- save_cluster_json @instances_filename
154
-
162
+ # Write out to the terminal the connection information for the servers and workers
163
+ #
164
+ # @return [nil] Only prints to the screen. No return is expected
165
+ def print_connection_info
155
166
  # Print out some debugging commands (probably work on mac/linux only)
156
167
  puts ''
157
168
  puts 'Server SSH Command:'
158
-
159
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
160
177
  end
161
178
 
162
179
  def create_workers(number_of_instances, options = {}, user_id = 'unknown_user')
@@ -176,7 +193,7 @@ module OpenStudio
176
193
  }
177
194
  options = defaults.merge(options)
178
195
 
179
- # for backwards compatibilty, still allow security_group
196
+ # for backwards compatibility, still allow security_group
180
197
  if options[:security_group]
181
198
  warn 'Pass security_groups as an array instead of security_group. security_group will be deprecated in 0.4.0'
182
199
  options[:security_groups] = [options[:security_group]]
@@ -189,10 +206,7 @@ module OpenStudio
189
206
 
190
207
  fail "Can't create workers without a server instance running" if @os_aws.server.nil?
191
208
 
192
- if number_of_instances == 0
193
- puts ''
194
- puts 'No workers requested'
195
- else
209
+ unless number_of_instances == 0
196
210
  worker_options = {
197
211
  user_id: options[:user_id],
198
212
  tags: options[:tags],
@@ -205,19 +219,9 @@ module OpenStudio
205
219
  # end
206
220
 
207
221
  @os_aws.launch_workers(options[:image_id], options[:instance_type], number_of_instances, worker_options)
208
-
209
- # Add the worker data to the JSON
210
- save_cluster_json @instances_filename
211
-
212
- puts ''
213
- puts 'Worker SSH Command:'
214
- @os_aws.workers.each do |worker|
215
- puts "ssh -i #{@os_aws.private_key_file_name} ubuntu@#{worker.data[:dns]}"
216
- end
217
222
  end
218
223
 
219
- puts ''
220
- puts 'Waiting for server/worker configurations'
224
+ logger.info 'Waiting for server/worker configurations'
221
225
 
222
226
  @os_aws.configure_server_and_workers
223
227
  end
@@ -232,8 +236,9 @@ module OpenStudio
232
236
  end
233
237
 
234
238
  # Save a JSON with information about the cluster that was configured.
239
+ #
235
240
  # @param filename [String] Path and filename to save the JSON file
236
- def save_cluster_json(filename)
241
+ def save_cluster_info(filename)
237
242
  File.open(filename, 'w') { |f| f << JSON.pretty_generate(cluster_info) }
238
243
  end
239
244
 
@@ -242,29 +247,71 @@ module OpenStudio
242
247
  @os_aws.describe_availability_zones
243
248
  end
244
249
 
245
- # Stop the entire cluster
246
- def stop
247
- puts "Stoping any instance with group ID: #{@os_aws.group_uuid}"
250
+ # Delete the key pair. Make sure that this happens at the end of whatever you are running, because you
251
+ # will not be able to connect to the instance after you do this.
252
+ def delete_key_pair
253
+ @os_aws.delete_key_pair
254
+ end
248
255
 
249
- stop_instances_by_group_id(@os_aws.group_uuid)
256
+ # Return the description of the instances in the GroupUUID
257
+ #
258
+ # @example Return Example
259
+ # [{:instance_id=>"i-45f924ac",
260
+ # :image_id=>"ami-845a54ec",
261
+ # :state=>{:code=>48, :name=>"terminated"},
262
+ # :private_dns_name=>"",
263
+ # :public_dns_name=>"",
264
+ # :state_transition_reason=>"User initiated (2015-06-01 21:50:40 GMT)",
265
+ # :key_name=>"os-key-pair-275a3bf436004c04a1a347ff36337f16",
266
+ # :ami_launch_index=>0,
267
+ # :product_codes=>[],
268
+ # :instance_type=>"m3.medium",
269
+ # :launch_time=>2015-06-01 21:13:18 UTC,
270
+ # :placement=>
271
+ # {:availability_zone=>"us-east-1e", :group_name=>"", :tenancy=>"default"},
272
+ # :monitoring=>{:state=>"disabled"},
273
+ # :state_reason=>
274
+ # {:code=>"Client.UserInitiatedShutdown",
275
+ # :message=>"Client.UserInitiatedShutdown: User initiated shutdown"},
276
+ # :architecture=>"x86_64",
277
+ # :root_device_type=>"ebs",
278
+ # :root_device_name=>"/dev/sda1",
279
+ # :block_device_mappings=>[],
280
+ # :virtualization_type=>"hvm",
281
+ # :client_token=>"",
282
+ # :tags=>
283
+ # [{:key=>"Purpose", :value=>"OpenStudioServer"},
284
+ # {:key=>"NumberOfProcessors", :value=>"1"},
285
+ # {:key=>"GroupUUID", :value=>"275a3bf436004c04a1a347ff36337f16"},
286
+ # {:key=>"Name", :value=>"OpenStudio-Server"},
287
+ # {:key=>"UserID", :value=>"unknown_user"}],
288
+ # :security_groups=>
289
+ # [{:group_name=>"openstudio-server-sg-v2.1", :group_id=>"sg-8740f3ea"}],
290
+ # :hypervisor=>"xen",
291
+ # :network_interfaces=>[],
292
+ # :ebs_optimized=>false}]
293
+ def describe_instances
294
+ @os_aws.describe_instances
250
295
  end
251
296
 
252
- # openstudio_instance_type as symbol
253
- def stop_instances(group_id, openstudio_instance_type)
254
- instances = @os_aws.describe_running_instances(group_id, openstudio_instance_type.to_sym)
255
- ids = instances.map { |k, _| k[:instance_id] }
297
+ # Return the list of all the instances that are running on the account in the availablity zone
298
+ def total_instances_count
299
+ @os_aws.total_instances_count
300
+ end
256
301
 
257
- resp = []
258
- resp = @os_aws.stop_instances(ids).to_hash unless ids.empty?
259
- resp
302
+ # Return the estimated cost for EC2 instances
303
+ def estimated_charges
304
+ @os_cloudwatch.estimated_charges
260
305
  end
261
306
 
262
- # Warning, it appears that this stops all the instances
263
- def stop_instances_by_group_id(group_id)
264
- instances = @os_aws.describe_running_instances(group_id)
307
+ # Stop running instances
308
+ #
309
+ # @param group_id [String] The unique group identifier for the OpenStudio cluster.
310
+ # @param openstudio_instance_type [Symbol] The type of instance (:server or :worker)
311
+ def stop_instances(group_id, openstudio_instance_type)
312
+ instances = @os_aws.describe_running_instances(group_id, openstudio_instance_type.to_sym)
265
313
  ids = instances.map { |k, _| k[:instance_id] }
266
314
 
267
- puts "Stoping the following instances #{ids}"
268
315
  resp = []
269
316
  resp = @os_aws.stop_instances(ids).to_hash unless ids.empty?
270
317
  resp
@@ -272,26 +319,30 @@ module OpenStudio
272
319
 
273
320
  # @params(ids): array of instance ids
274
321
  def terminate_instances(ids)
275
- puts "Terminating the following instances #{ids}"
322
+ logger.info "Terminating the following instances #{ids}"
276
323
  resp = []
277
324
  resp = @os_aws.terminate_instances(ids).to_hash unless ids.empty?
278
325
  resp
279
326
  end
280
327
 
281
- # Warning, it appears that this terminates all the instances
328
+ # Warning, this appears that it terminates all the instances
282
329
  def terminate_instances_by_group_id(group_id)
330
+ fail "Group ID not defined" unless group_id
331
+
283
332
  instances = @os_aws.describe_running_instances(group_id)
333
+ logger.info instances
284
334
  ids = instances.map { |k, _| k[:instance_id] }
285
335
 
286
- puts "Terminating the following instances #{ids}"
336
+ logger.info "Terminating the following instances #{ids}"
287
337
  resp = []
288
338
  resp = @os_aws.terminate_instances(ids).to_hash unless ids.empty?
339
+
289
340
  resp[:terminating_instances].first[:current_state][:name] == 'shutting-down'
290
341
  end
291
342
 
292
- # Terminate the entire cluster
343
+ # Terminate the entire cluster based on the member variable's group_uuid.
293
344
  def terminate
294
- puts "Terminating any instance with group ID: #{@os_aws.group_uuid}"
345
+ logger.info "Terminating any instance with GroupUUID: #{@os_aws.group_uuid}"
295
346
 
296
347
  terminate_instances_by_group_id(@os_aws.group_uuid)
297
348
  end
@@ -303,7 +354,7 @@ module OpenStudio
303
354
  if h[:location] == 'AWS'
304
355
  @os_aws.find_server(h)
305
356
  else
306
- puts "Instance file '#{filename}' does not have the location of 'AWS'"
357
+ logger.info "Instance file '#{filename}' does not have the location of 'AWS'"
307
358
  return false
308
359
  end
309
360
 
@@ -1,57 +1,38 @@
1
1
  module OpenStudio
2
2
  module Aws
3
3
  class Config
4
- include Logging
5
-
6
4
  attr_accessor :access_key
7
5
  attr_accessor :secret_key
8
6
 
9
7
  def initialize(yml_config_file = nil)
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?
8
+ @yml_config_file = yml_config_file
9
+ @config = nil
24
10
 
11
+ if @yml_config_file.nil?
12
+ @yml_config_file = File.join(File.expand_path('~'), 'aws_config.yml')
25
13
  unless File.exist?(@yml_config_file)
26
14
  write_config_file
27
- fail "Config file not found. A template has been added, please edit and save: #{@yml_config_file}"
15
+ fail "No Config File in user home directory. A template has been added, please edit and save: #{@yml_config_file}"
28
16
  exit 1
29
17
  end
18
+ end
30
19
 
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
20
+ begin
21
+ @config = YAML.load(File.read(@yml_config_file))
22
+ @access_key = @config['access_key_id']
23
+ @secret_key = @config['secret_access_key']
24
+ rescue
25
+ raise "Couldn't read config file #{@yml_config_file}. Delete file then recreate by rerunning script"
42
26
  end
43
27
  end
44
28
 
45
29
  private
46
30
 
47
31
  def write_config_file
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 }
32
+ File.open(@yml_config_file, 'w') do |f|
33
+ f << "access_key_id: YOUR_ACCESS_KEY_ID\n"
34
+ f << "secret_access_key: YOUR_SECRET_ACCESS_KEY\n"
35
+ end
55
36
  end
56
37
  end
57
38
  end
@@ -1,5 +1,5 @@
1
1
  module OpenStudio
2
2
  module Aws
3
- VERSION = '0.3.2'
3
+ VERSION = '0.4.0.alpha1'
4
4
  end
5
5
  end
@@ -0,0 +1,22 @@
1
+ # From: https://github.com/rails/rails/blob/001b270611cd9cb653124775899bdbc2548333ab/activesupport/lib/active_support/core_ext/hash/except.rb
2
+ class Hash
3
+ # Returns a hash that includes everything but the given keys.
4
+ # hash = { a: true, b: false, c: nil}
5
+ # hash.except(:c) # => { a: true, b: false}
6
+ # hash # => { a: true, b: false, c: nil}
7
+ #
8
+ # This is useful for limiting a set of parameters to everything but a few known toggles:
9
+ # @person.update(params[:person].except(:admin))
10
+ def except(*keys)
11
+ dup.except!(*keys)
12
+ end
13
+
14
+ # Replaces the hash without the given keys.
15
+ # hash = { a: true, b: false, c: nil}
16
+ # hash.except!(:c) # => { a: true, b: false}
17
+ # hash # => { a: true, b: false }
18
+ def except!(*keys)
19
+ keys.each { |key| delete(key) }
20
+ self
21
+ end
22
+ end
@@ -21,6 +21,8 @@
21
21
  # Class for managing the AMI ids based on the openstudio version and the openstudio-server version
22
22
 
23
23
  class OpenStudioAmis
24
+ include Logging
25
+
24
26
  VALID_OPTIONS = [
25
27
  :openstudio_version, :openstudio_server_version, :host, :url, :stable
26
28
  ]
@@ -100,6 +102,7 @@ class OpenStudioAmis
100
102
  json[version]
101
103
  end
102
104
 
105
+ # Return the AMIs for the server and worker. Version 2 also does a lookup of the stable version
103
106
  def get_ami_version_2
104
107
  json = list
105
108
 
@@ -114,9 +117,29 @@ class OpenStudioAmis
114
117
  elsif @options[:openstudio_version] != 'default'
115
118
  if @options[:stable]
116
119
  stable = json[:openstudio][@options[:openstudio_version].to_sym][:stable]
117
- fail "Could not find a stable version for openstudio version #{@options[:openstudio_version]}" unless stable
118
- value = json[:openstudio][@options[:openstudio_version].to_sym][stable.to_sym]
119
- amis = value[:amis]
120
+ if stable
121
+ value = json[:openstudio][@options[:openstudio_version].to_sym][stable.to_sym]
122
+ amis = value[:amis]
123
+ else
124
+ logger.info "Could not find a stable version for OpenStudio version #{@options[:openstudio_version]}. "\
125
+ "Looking up older versions to find the latest stable." unless stable
126
+
127
+ json[:openstudio].each do |os_version, values|
128
+ next if os_version == :default
129
+ if values.key? :stable
130
+ # don't check versions newer than what we are requesting
131
+ next if os_version.to_s.to_version > @options[:openstudio_version].to_s.to_version
132
+ stable = json[:openstudio][os_version][:stable]
133
+ logger.info "Found a stable version for OpenStudio version #{os_version} with OpenStudio Server version #{stable}"
134
+ value = values[stable.to_sym]
135
+ amis = value[:amis]
136
+
137
+ break
138
+ end
139
+ end
140
+
141
+ fail "Could not find a stable version for openstudio version #{@options[:openstudio_version]}" unless amis
142
+ end
120
143
  else
121
144
  # return the default version (which is the latest)
122
145
  default = json[:openstudio][@options[:openstudio_version].to_sym][:default]
@@ -126,6 +149,8 @@ class OpenStudioAmis
126
149
  end
127
150
  end
128
151
 
152
+ logger.info "AMI IDs are #{amis}" if amis
153
+
129
154
  amis
130
155
  end
131
156
 
@@ -138,6 +163,7 @@ class OpenStudioAmis
138
163
 
139
164
  url = URI.parse(uri_str)
140
165
  req = Net::HTTP::Get.new(url.path)
166
+ logger.info "Fetching AMI list from #{uri_str}"
141
167
  response = Net::HTTP.start(url.host, url.port) { |http| http.request(req) }
142
168
  case response
143
169
  when Net::HTTPSuccess then
@@ -1,4 +1,3 @@
1
- # NOTE: Do not modify this file as it is copied over. Modify the source file and rerun rake import_files
2
1
  ######################################################################
3
2
  # Copyright (c) 2008-2014, Alliance for Sustainable Energy.
4
3
  # All rights reserved.
@@ -36,7 +35,7 @@ class OpenStudioAwsInstance
36
35
  @key_pair_name = key_pair_name
37
36
  @security_groups = security_groups
38
37
  @group_uuid = group_uuid.to_s
39
- @init_timestamp = Time.now # This is the timestamp and is typically just tracked for the server
38
+ @init_timestamp = Time.now # This is the timestamp and is typically just tracked for the server
40
39
  @private_key = private_key
41
40
  @private_key_file_name = private_key_file_name
42
41
  @proxy = proxy
@@ -141,12 +140,12 @@ class OpenStudioAwsInstance
141
140
  t = tag.split('=')
142
141
  if t.size != 2
143
142
  logger.error "Tag '#{t}' not defined or does not have an equal sign"
144
- puts "Tag '#{t}' not defined or does not have an equal sign"
143
+ fail "Tag '#{t}' not defined or does not have an equal sign"
145
144
  next
146
145
  end
147
146
  if %w(Name GroupUUID NumberOfProcessors Purpose UserID).include? t[0]
148
147
  logger.error "Tag name '#{t[0]}' is a reserved tag"
149
- puts "Tag name '#{t[0]}' is a reserved tag"
148
+ fail "Tag name '#{t[0]}' is a reserved tag"
150
149
  next
151
150
  end
152
151
 
@@ -162,7 +161,7 @@ class OpenStudioAwsInstance
162
161
  tags: aws_tags
163
162
  )
164
163
  rescue Aws::EC2::Errors::InvalidInstanceIDNotFound
165
- sleep 1000
164
+ sleep 5
166
165
  retry unless (tries -= 1).zero?
167
166
  end
168
167
 
@@ -270,6 +269,8 @@ class OpenStudioAwsInstance
270
269
  processors = 1
271
270
  if lookup.key?(instance)
272
271
  processors = lookup[instance]
272
+ else
273
+ # logger.warn "Could not find the number of processors for instance type of #{instance}" if logger
273
274
  end
274
275
 
275
276
  if @openstudio_instance_type == :server
@@ -306,13 +307,13 @@ class OpenStudioAwsInstance
306
307
  # port 22 might not be available immediately after the instance finishes launching
307
308
  return if retries == 5
308
309
  retries += 1
309
- sleep 1
310
+ sleep 2
310
311
  retry
311
312
  rescue
312
313
  # Unknown upload error, retry
313
314
  return if retries == 5
314
315
  retries += 1
315
- sleep 1
316
+ sleep 2
316
317
  retry
317
318
  end
318
319
  end
@@ -342,11 +343,11 @@ class OpenStudioAwsInstance
342
343
  rescue Net::SSH::HostKeyMismatch => e
343
344
  e.remember_host!
344
345
  logger.info('key mismatch, retry')
345
- sleep 1
346
+ sleep 2
346
347
  retry
347
348
  rescue SystemCallError, Timeout::Error => e
348
349
  # port 22 might not be available immediately after the instance finishes launching
349
- sleep 1
350
+ sleep 2
350
351
  logger.info('SystemCallError, Waiting for SSH to become available')
351
352
  retry
352
353
  end
@@ -391,7 +392,7 @@ class OpenStudioAwsInstance
391
392
  rescue SystemCallError, Timeout::Error => e
392
393
  # port 22 might not be available immediately after the instance finishes launching
393
394
  sleep 10
394
- logger.info('Timeout. Perhaps there is a communication error to EC2? Will try again in 10 seconds')
395
+ logger.info('Timeout. Perhaps there is a communication error to EC2? Will try again')
395
396
  retry
396
397
  end
397
398
 
@@ -405,12 +406,12 @@ class OpenStudioAwsInstance
405
406
  # port 22 might not be available immediately after the instance finishes launching
406
407
  return if retries == 5
407
408
  retries += 1
408
- sleep 1
409
+ sleep 2
409
410
  retry
410
411
  rescue
411
412
  return if retries == 5
412
413
  retries += 1
413
- sleep 1
414
+ sleep 2
414
415
  retry
415
416
  end
416
417
  end
@@ -420,7 +421,7 @@ class OpenStudioAwsInstance
420
421
  # store some of the data into a custom struct. The instance is the full description. The remaining fields are
421
422
  # just easier accessors to the data in the raw request except for procs which is a custom request.
422
423
  def create_struct(instance, procs)
423
- instance_struct = Struct.new(:instance, :id, :ip, :dns, :procs, :availability_zone, :private_ip_address)
424
+ instance_struct = Struct.new(:instance, :id, :ip, :dns, :procs, :availability_zone, :private_ip_address, :launch_time)
424
425
  s = instance_struct.new(
425
426
  instance,
426
427
  instance[:instance_id],
@@ -428,7 +429,8 @@ class OpenStudioAwsInstance
428
429
  instance[:public_dns_name],
429
430
  procs,
430
431
  instance[:placement][:availability_zone],
431
- instance[:private_ip_address]
432
+ instance[:private_ip_address],
433
+ instance[:launch_time]
432
434
  )
433
435
 
434
436
  # store some values into the member variables
@@ -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-2014, Alliance for Sustainable Energy.
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