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 +14 -0
- data/README.md +9 -2
- data/Rakefile +7 -0
- data/ec2launcher.gemspec +3 -0
- data/lib/ec2launcher.rb +7 -6
- data/lib/ec2launcher/block_device_builder.rb +77 -33
- data/lib/ec2launcher/hostname_generator.rb +8 -1
- data/lib/ec2launcher/version.rb +1 -1
- data/test/ec2launcher/dsl/config_parser_test.rb +39 -0
- data/test/test_helper.rb +3 -0
- metadata +39 -3
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
|
-
#
|
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
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
|
-
|
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 =
|
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
|
-
|
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 [
|
187
|
+
# @param [AWS::EC2::SnapshotCollection] snapshots collection of snapshots to examine
|
192
188
|
#
|
193
|
-
# @return [
|
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
|
-
|
203
|
-
|
204
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
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: #{
|
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"] ==
|
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 =
|
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]
|
data/lib/ec2launcher/version.rb
CHANGED
@@ -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
|
data/test/test_helper.rb
ADDED
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.
|
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-
|
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:
|