ec2launcher 1.3.10 → 1.3.12

Sign up to get free protection for your applications and to get access to all the features.
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: