ec2launcher 1.3.10 → 1.3.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/CHANGELOG.md CHANGED
@@ -1,3 +1,17 @@
1
+ ## 1.3.12
2
+
3
+ * Use run_with_backoff when searching for AMI.
4
+ * Fixed bug introduced by BlockDeviceBuilder refactoring.
5
+
6
+ ## 1.3.11
7
+
8
+ * Fixed logging bug in BlockDeviceBuilder (again).
9
+
10
+ ## 1.3.10
11
+
12
+ * Made additional methods in BlockDeviceBuilder public for reuse elsewhere.
13
+ * Fixed small bug in BlockDeviceBuilder when unable to retrieve existing Logger.
14
+
1
15
  ## 1.3.9
2
16
 
3
17
  * More cleanup to terminator code.
data/README.md CHANGED
@@ -1,4 +1,7 @@
1
- # ec2launcher
1
+ # EC2Launcher
2
+ [![Build Status](https://secure.travis-ci.org/StudyBlue/ec2launcher.png)](http://travis-ci.org/StudyBlue/ec2launcher)
3
+ [![Dependency Status](https://gemnasium.com/StudyBlue/ec2launcher.png)](https://gemnasium.com/StudyBlue/ec2launcher)
4
+ [![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/StudyBlue/ec2launcher)
2
5
 
3
6
  A tool to help launch Amazon EC2 instances.
4
7
 
@@ -13,4 +16,8 @@ All contributions are welcome: ideas, patches, documentation, bug reports, compl
13
16
 
14
17
  # Support
15
18
 
16
- [ec2launcher Google Groups](http://groups.google.com/group/ec2launcher-user)
19
+ [ec2launcher Google Groups](http://groups.google.com/group/ec2launcher-user)
20
+
21
+ # Authors and Contributors
22
+
23
+ * Sean Laurent
data/Rakefile CHANGED
@@ -1,2 +1,9 @@
1
1
  #!/usr/bin/env rake
2
2
  require "bundler/gem_tasks"
3
+ require 'rake/testtask'
4
+ Rake::TestTask.new do |t|
5
+ t.libs << 'lib/ec2launcher'
6
+ t.test_files = FileList['test/ec2launcher/*_test.rb', "test/ec2launcher/dsl/*_test.rb"]
7
+ t.verbose = true
8
+ end
9
+ task :default => :test
data/ec2launcher.gemspec CHANGED
@@ -16,4 +16,7 @@ Gem::Specification.new do |gem|
16
16
 
17
17
  gem.add_runtime_dependency "aws-sdk", [">= 1.6.6"]
18
18
  gem.add_runtime_dependency "log4r"
19
+
20
+ gem.add_development_dependency "minitest"
21
+ gem.add_development_dependency "rake"
19
22
  end
data/lib/ec2launcher.rb CHANGED
@@ -164,11 +164,8 @@ module EC2Launcher
164
164
  sg_map = { }
165
165
  AWS.start_memoizing
166
166
  @ec2.security_groups.each do |sg|
167
- if ec2_subnet.nil?
168
- next unless sg.vpc_id.nil?
169
- else
170
- next unless ec2_subnet.vpc_id == sg.vpc_id
171
- end
167
+ next if ec2_subnet.nil? && sg.vpc_id
168
+ next if ec2_subnet && ec2_subnet.vpc_id != sg.vpc_id
172
169
  sg_map[sg.name] = sg
173
170
  end
174
171
  AWS.stop_memoizing
@@ -178,6 +175,7 @@ module EC2Launcher
178
175
  missing_security_groups = []
179
176
  security_groups.each do |sg_name|
180
177
  missing_security_groups << sg_name unless sg_map.has_key?(sg_name)
178
+ puts sg_name
181
179
  security_group_ids << sg_map[sg_name].security_group_id
182
180
  end
183
181
 
@@ -216,7 +214,10 @@ module EC2Launcher
216
214
  ##############################
217
215
  ami_name_match = @application.ami_name
218
216
  ami_name_match ||= @environment.ami_name
219
- ami = find_ami(instance_architecture, instance_virtualization, ami_name_match, @options.ami_id)
217
+ ami = nil
218
+ run_with_backoff(60, 1, "searching for ami") do
219
+ ami = find_ami(instance_architecture, instance_virtualization, ami_name_match, @options.ami_id)
220
+ end
220
221
 
221
222
  ##############################
222
223
  # DOMAIN NAME
@@ -2,6 +2,7 @@
2
2
  # Copyright (c) 2012 Sean Laurent
3
3
  #
4
4
  require 'ec2launcher/defaults'
5
+ require 'ec2launcher/backoff_runner'
5
6
  require 'log4r'
6
7
 
7
8
  include Log4r
@@ -10,6 +11,8 @@ module EC2Launcher
10
11
  # Helper class to build EC2 block device definitions.
11
12
  #
12
13
  class BlockDeviceBuilder
14
+ include BackoffRunner
15
+
13
16
  attr_reader :block_device_mappings
14
17
  attr_reader :block_device_tags
15
18
 
@@ -25,10 +28,11 @@ module EC2Launcher
25
28
  @block_device_tags = {}
26
29
 
27
30
  begin
28
- @log = Logger['ec2launcher']
31
+ @log = Log4r::Logger['ec2launcher']
29
32
  rescue
30
- @log = Logger.new 'ec2launcher'
31
33
  end
34
+
35
+ @log ||= Log4r::Logger.new 'ec2launcher'
32
36
  end
33
37
 
34
38
  # Generates the mappings for ephemeral and ebs volumes.
@@ -177,37 +181,38 @@ module EC2Launcher
177
181
  AWS.stop_memoizing
178
182
  end
179
183
 
180
- public
181
- # Retrieves the latest set of completed snapshots for a RAID array of EBS volumes.
182
- #
183
- # Volumes must have the following tags:
184
- # * host
185
- # * volumeName
186
- # * time
187
- #
188
- # @param [String] hostname FQDN for new host
184
+ private
189
185
  # @param [String] purpose purpose of RAID array, which is stored in the `purpose` tag for snapshots/volumes
190
186
  # and is part of the snapshot name.
191
- # @param [Integer] count number of EBS snapshots to look for
187
+ # @param [AWS::EC2::SnapshotCollection] snapshots collection of snapshots to examine
192
188
  #
193
- # @return [Hash<Integer, AWS::EC2::Snapshot>] mapping of RAID device numbers (zero based) to AWS Snapshots.
194
- #
195
- def get_latest_raid_snapshot_mapping(hostname, purpose, count)
196
- @log.info "Retrieving list of snapshots ..."
197
- result = @ec2.snapshots.tagged("host").tagged_values(hostname).tagged("volumeName").tagged_values("*raid*").tagged("time")
198
-
199
- @log.info "Building list of snapshots to clone (#{purpose}) for '#{hostname}'..."
189
+ # @return [Array<AWS::EC2::Snapshot>] list of matching snapshots
190
+ def build_snapshot_clone_list(purpose, snapshots)
200
191
  snapshot_name_regex = /#{purpose} raid.*/
201
192
  host_snapshots = []
202
- result.each do |s|
203
- next if snapshot_name_regex.match(s.tags["volumeName"]).nil?
204
- host_snapshots << s if s.status == :completed
193
+ snapshots.each do |s|
194
+ name_no_match = false
195
+ run_with_backoff(60, 1, "searching for snapshots") do
196
+ name_no_match = snapshot_name_regex.match(s.tags["volumeName"]).nil?
197
+ end
198
+ next if name_no_match
199
+
200
+ run_with_backoff(60, 1, "searching for snapshots") do
201
+ host_snapshots << s if s.status == :completed
202
+ end
205
203
  end
204
+ host_snapshots
205
+ end
206
206
 
207
- # Bucket the snapshots based on volume number e.g. "raid (1)" vs "raid (2)"
207
+ private
208
+ # Creates a mapping of volume numbers to snapshots.
209
+ #
210
+ # @param [Array<AWS::EC2::Snapshot>] snapshots list of matching snapshots
211
+ # @result [Hash<String, AWS::EC2::Snapshot>] map of volume numbers as strings ("1", "2", etc.) to snapshots
212
+ def bucket_snapshots_by_volume_number(snapshots)
208
213
  snapshot_buckets = { }
209
214
  volume_number_regex = /raid \((\d)\)$/
210
- host_snapshots.each do |snapshot|
215
+ snapshots.each do |snapshot|
211
216
  next if snapshot.tags["time"].nil?
212
217
 
213
218
  volume_name = snapshot.tags["volumeName"]
@@ -223,14 +228,14 @@ module EC2Launcher
223
228
  snapshot_buckets[raid_number] = [] if snapshot_buckets[raid_number].nil?
224
229
  snapshot_buckets[raid_number] << snapshot
225
230
  end
231
+ snapshot_buckets
232
+ end
226
233
 
227
- # Sort the snapshots in each bucket by time
228
- snapshot_buckets.keys.each do |key|
229
- snapshot_buckets[key].sort! do |a, b|
230
- b.tags["time"] <=> a.tags["time"]
231
- end
232
- end
233
-
234
+ private
235
+ # Find the most recent backup time that all snapshots have in common.
236
+ #
237
+ # @param [Hash<String, AWS::EC2::Snapshot>] snapshot_buckets map of volume numbers as strings ("1", "2", etc.) to snapshots
238
+ def get_most_recent_common_snapshot_time(snapshot_buckets)
234
239
  # We need to find the most recent backup time that all snapshots have in common.
235
240
  #
236
241
  # For example, we may have the following snapshots for "raid (1)":
@@ -251,15 +256,54 @@ module EC2Launcher
251
256
  most_recent_dates << snapshot.tags["time"].to_s
252
257
  end
253
258
  most_recent_dates.sort!
259
+ most_recent_dates[0]
260
+ end
261
+
262
+ public
263
+ # Retrieves the latest set of completed snapshots for a RAID array of EBS volumes.
264
+ #
265
+ # Volumes must have the following tags:
266
+ # * host
267
+ # * volumeName
268
+ # * time
269
+ #
270
+ # @param [String] hostname FQDN for new host
271
+ # @param [String] purpose purpose of RAID array, which is stored in the `purpose` tag for snapshots/volumes
272
+ # and is part of the snapshot name.
273
+ # @param [Integer] count number of EBS snapshots to look for
274
+ #
275
+ # @return [Hash<Integer, AWS::EC2::Snapshot>] mapping of RAID device numbers (zero based) to AWS Snapshots.
276
+ #
277
+ def get_latest_raid_snapshot_mapping(hostname, purpose, count)
278
+ @log.info "Retrieving list of snapshots ..."
279
+ result = @ec2.snapshots.tagged("host").tagged_values(hostname).tagged("volumeName").tagged_values("*raid*").tagged("time")
280
+
281
+ @log.info "Building list of snapshots to clone (#{purpose}) for '#{hostname}'..."
282
+ snapshot_name_regex = /#{purpose} raid.*/
283
+ host_snapshots = build_snapshot_clone_list(purpose, result)
284
+
285
+ # Bucket the snapshots based on volume number e.g. "raid (1)" vs "raid (2)"
286
+ snapshot_buckets = bucket_snapshots_by_volume_number(host_snapshots)
287
+
288
+ # Sort the snapshots in each bucket by time
289
+ snapshot_buckets.keys.each do |key|
290
+ snapshot_buckets[key].sort! do |a, b|
291
+ b.tags["time"] <=> a.tags["time"]
292
+ end
293
+ end
294
+
295
+ # We need to find the most recent backup time that all snapshots have in common.
296
+ most_recent_date = get_most_recent_common_snapshot_time(snapshot_buckets)
254
297
 
255
- @log.info "Most recent snapshot: #{most_recent_dates[0]}"
298
+ @log.info "Most recent snapshot: #{most_recent_date}"
256
299
 
300
+ # Find snapshots for the specified date
257
301
  snapshot_mapping = { }
258
302
  AWS.memoize do
259
303
  snapshot_buckets.keys.each do |index|
260
304
  found = false
261
305
  snapshot_buckets[index].each do |snapshot|
262
- if snapshot.tags["time"] == most_recent_dates[0]
306
+ if snapshot.tags["time"] == most_recent_date
263
307
  snapshot_mapping[index] = snapshot
264
308
  found = true
265
309
  break
@@ -4,9 +4,13 @@
4
4
  require 'rubygems'
5
5
  require 'aws-sdk'
6
6
 
7
+ require 'ec2launcher/backoff_runner'
8
+
7
9
  module EC2Launcher
8
10
  # Helper class to generate sequential, numbered host names
9
11
  class HostnameGenerator
12
+ include BackoffRunner
13
+
10
14
  #
11
15
  # @param [AWS::EC2] ec2 EC2 object used to query for existing instances
12
16
  # @param [EC2Launcher::Environment] environment Environment to use for generating host names
@@ -70,7 +74,10 @@ module EC2Launcher
70
74
  def load_instances(prefix, suffix)
71
75
  @server_name_cache = []
72
76
  AWS.memoize do
73
- server_instances = @ec2.instances.filter("tag:Name", "#{prefix}*#{suffix}*")
77
+ server_instances = nil
78
+ run_with_backoff(60, 1, "searching for instances") do
79
+ server_instances = @ec2.instances.filter("tag:Name", "#{prefix}*#{suffix}*")
80
+ end
74
81
  server_instances.each do |i|
75
82
  next if i.status == :terminated
76
83
  @server_name_cache << i.tags[:Name]
@@ -2,5 +2,5 @@
2
2
  # Copyright (c) 2012 Sean Laurent
3
3
  #
4
4
  module EC2Launcher
5
- VERSION = "1.3.10"
5
+ VERSION = "1.3.12"
6
6
  end
@@ -0,0 +1,39 @@
1
+ require_relative "../../test_helper"
2
+
3
+ class ConfigParserTest < MiniTest::Unit::TestCase
4
+ def test_full_config_parses_correctly
5
+ sample_config_erb = %q{
6
+ config do
7
+ environments "environments"
8
+ applications "applications"
9
+
10
+ package_manager "yum"
11
+ config_manager "chef"
12
+ end
13
+ }.gsub(/^ /, '')
14
+
15
+ config_dsl = EC2Launcher::DSL::ConfigDSL.execute(sample_config_erb)
16
+ refute config_dsl.nil?
17
+ refute config_dsl.config.nil?
18
+
19
+ config = config_dsl.config
20
+ assert_equal "yum", config.package_manager
21
+ assert_equal "chef", config.config_manager
22
+
23
+ assert_kind_of Array, config.applications
24
+ assert_kind_of Array, config.environments
25
+
26
+ assert_equal "applications", config.applications[0]
27
+ assert_equal "environments", config.environments[0]
28
+ end
29
+
30
+ def test_empty_config_parses_correctly
31
+ sample_config_erb = %q{
32
+ config do
33
+ end
34
+ }.gsub(/^ /, '')
35
+ config_dsl = EC2Launcher::DSL::ConfigDSL.execute(sample_config_erb)
36
+ refute config_dsl.nil?
37
+ refute config_dsl.config.nil?
38
+ end
39
+ end
@@ -0,0 +1,3 @@
1
+ require 'minitest/autorun'
2
+ require 'minitest/pride'
3
+ require File.expand_path('../../lib/ec2launcher.rb', __FILE__)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ec2launcher
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.10
4
+ version: 1.3.12
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-10-30 00:00:00.000000000 Z
12
+ date: 2012-11-09 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: aws-sdk
@@ -43,6 +43,38 @@ dependencies:
43
43
  - - ! '>='
44
44
  - !ruby/object:Gem::Version
45
45
  version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: minitest
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: rake
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
46
78
  description: Tool to manage application configurations and launch new EC2 instances
47
79
  based on the configurations.
48
80
  email:
@@ -85,6 +117,8 @@ files:
85
117
  - startup-scripts/runurl
86
118
  - startup-scripts/setup.rb
87
119
  - startup-scripts/setup_instance.rb
120
+ - test/ec2launcher/dsl/config_parser_test.rb
121
+ - test/test_helper.rb
88
122
  - yard_extensions/dsl_attribute_handler.rb
89
123
  homepage: https://github.com/StudyBlue/ec2launcher
90
124
  licenses: []
@@ -110,5 +144,7 @@ rubygems_version: 1.8.24
110
144
  signing_key:
111
145
  specification_version: 3
112
146
  summary: Tool to launch EC2 instances.
113
- test_files: []
147
+ test_files:
148
+ - test/ec2launcher/dsl/config_parser_test.rb
149
+ - test/test_helper.rb
114
150
  has_rdoc: