poolparty 1.6.8 → 1.6.9
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +12 -2
- data/VERSION.yml +2 -1
- data/bin/cloud +4 -1
- data/bin/cloud-run +2 -2
- data/bin/cloud-show +11 -10
- data/lib/cloud_providers/connections.rb +4 -2
- data/lib/cloud_providers/ec2/ec2.rb +58 -39
- data/lib/cloud_providers/ec2/ec2_instance.rb +50 -40
- data/lib/cloud_providers/ec2/helpers/authorize.rb +8 -3
- data/lib/cloud_providers/ec2/helpers/elastic_auto_scaler.rb +7 -4
- data/lib/cloud_providers/ec2/helpers/revoke.rb +5 -5
- data/lib/cloud_providers/ec2/helpers/security_group.rb +29 -32
- data/lib/cloud_providers/remote_instance.rb.orig +162 -0
- data/lib/core/object.rb +16 -1
- data/lib/keypair.rb +21 -21
- data/lib/poolparty/chef.rb +71 -6
- data/lib/poolparty/chef_client.rb +6 -2
- data/lib/poolparty/chef_solo.rb +18 -2
- data/lib/poolparty/cloud.rb +13 -0
- data/lib/poolparty/cloud.rb.orig +432 -0
- data/lib/poolparty/pool.rb +36 -2
- metadata +7 -12
data/Rakefile
CHANGED
@@ -14,7 +14,17 @@ require 'config/jeweler' # setup gem configuration
|
|
14
14
|
|
15
15
|
task :default => [:test, :cleanup_test]
|
16
16
|
desc "Update vendor directory and run tests"
|
17
|
-
|
17
|
+
|
18
|
+
namespace :poolparty do
|
19
|
+
namespace :vendor do
|
20
|
+
desc "Fetch all the submodules"
|
21
|
+
task :submodules do
|
22
|
+
`git submodule update`
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
task :vendor => ["poolparty:vendor:submodules"]
|
18
28
|
|
19
29
|
task :cleanup_test do
|
20
30
|
::FileUtils.rm_rf "/tmp/poolparty"
|
@@ -83,4 +93,4 @@ Rake::RDocTask.new do |rd|
|
|
83
93
|
rd.rdoc_files.include("README.rdoc", "lib/**/*.rb")
|
84
94
|
rd.rdoc_dir = "rdoc"
|
85
95
|
# rd.template = "hanaa"
|
86
|
-
end
|
96
|
+
end
|
data/VERSION.yml
CHANGED
data/bin/cloud
CHANGED
@@ -23,6 +23,7 @@ EOS
|
|
23
23
|
opt :debug, "Debug the output", :type => :boolean, :default => false
|
24
24
|
opt :very_debug, "Set very debug mode on", :type => :boolean, :default => false
|
25
25
|
opt :name, "Name of the working cloud", :type => String, :default => nil
|
26
|
+
opt :chef_task, "Name of chef task to execute", :type => String, :default => 'default'
|
26
27
|
|
27
28
|
before_run do |command|
|
28
29
|
# Setup testing/debugging
|
@@ -38,9 +39,11 @@ EOS
|
|
38
39
|
exit
|
39
40
|
end
|
40
41
|
|
42
|
+
pool.chef_step command[:chef_task].to_sym
|
43
|
+
|
41
44
|
@loaded_pool = pool
|
42
45
|
@loaded_clouds = command[:name] ? [pool.clouds[command[:name]]] : pool.clouds.map {|name,cld|cld}
|
43
|
-
if @loaded_clouds.
|
46
|
+
if @loaded_clouds.size == 0
|
44
47
|
puts "No clouds loaded. Check your clouds.rb or -n option"
|
45
48
|
exit
|
46
49
|
end
|
data/bin/cloud-run
CHANGED
data/bin/cloud-show
CHANGED
@@ -6,8 +6,8 @@ require 'git-style-binary/command'
|
|
6
6
|
|
7
7
|
GitStyleBinary.command do
|
8
8
|
@theme = :short
|
9
|
-
|
10
|
-
version "PoolParty #{$0} command"
|
9
|
+
|
10
|
+
version "PoolParty #{$0} command"
|
11
11
|
banner <<-EOS
|
12
12
|
Usage: #{$0} #{all_options_string}
|
13
13
|
|
@@ -20,7 +20,7 @@ EOS
|
|
20
20
|
run do |command|
|
21
21
|
|
22
22
|
@loaded_clouds.each do |cld|
|
23
|
-
|
23
|
+
|
24
24
|
msg = [
|
25
25
|
"Cloud: #{cld.name}",
|
26
26
|
"----------------------------",
|
@@ -29,11 +29,12 @@ EOS
|
|
29
29
|
"Maximum instances: #{cld.maximum_instances}",
|
30
30
|
"Running on: #{cld.cloud_provider.name}",
|
31
31
|
"Keypair: #{cld.keypair.basename}",
|
32
|
-
"Security group: #{cld.cloud_provider.security_group_names}",
|
33
|
-
"Availability zones: #{cld.cloud_provider.availability_zones}",
|
34
|
-
"User:
|
32
|
+
"Security group: #{cld.cloud_provider.security_group_names.join(', ')}",
|
33
|
+
"Availability zones: #{cld.cloud_provider.availability_zones.join(', ')}",
|
34
|
+
"User: #{cld.user}",
|
35
|
+
"Active recipes: #{cld.chef._recipes(cld.pool.chef_step).join ", " }"
|
35
36
|
]
|
36
|
-
|
37
|
+
|
37
38
|
if cld.load_balancers.size > 0
|
38
39
|
load_balancers = cld.cloud_provider.load_balancers.first.running_load_balancers.map {|a| a[:dns_name]}
|
39
40
|
msg << "Load balancers: #{load_balancers.join("\n\t\t\t")}"
|
@@ -45,10 +46,10 @@ EOS
|
|
45
46
|
|
46
47
|
msg << available.join("\n\t\t\t")
|
47
48
|
end
|
48
|
-
|
49
|
+
|
49
50
|
puts msg.flatten
|
50
|
-
|
51
|
+
|
51
52
|
end
|
52
|
-
|
53
|
+
|
53
54
|
end
|
54
55
|
end
|
@@ -108,7 +108,7 @@ module CloudProviders
|
|
108
108
|
rsync_opts += %q% --rsync-path="sudo rsync"% unless user=="root"
|
109
109
|
rsync_opts += %q% --exclude=.svn --exclude=.git --exclude=.cvs %
|
110
110
|
cmd_string = "rsync -L -e 'ssh #{ssh_options}' #{rsync_opts} #{opts[:source]} #{user}@#{host}:#{destination_path}"
|
111
|
-
out = system_run(cmd_string)
|
111
|
+
out = system_run(cmd_string, :quiet => true)
|
112
112
|
out
|
113
113
|
end
|
114
114
|
|
@@ -137,7 +137,9 @@ module CloudProviders
|
|
137
137
|
while (chunk = stdin.readpartial(opts[:sysread]))
|
138
138
|
buf << chunk
|
139
139
|
unless chunk.nil? || chunk.empty?
|
140
|
-
|
140
|
+
if not opts[:quiet]
|
141
|
+
$stdout.write(chunk) #if debugging? || verbose?
|
142
|
+
end
|
141
143
|
end
|
142
144
|
end
|
143
145
|
err = stderr.readlines
|
@@ -10,37 +10,39 @@ rescue LoadError
|
|
10
10
|
EOM
|
11
11
|
end
|
12
12
|
|
13
|
+
require 'pp'
|
14
|
+
|
13
15
|
module CloudProviders
|
14
16
|
class Ec2 < CloudProvider
|
15
17
|
# Set the aws keys from the environment, or load from /etc/poolparty/env.yml if the environment variable is not set
|
16
18
|
def self.default_access_key
|
17
19
|
ENV['EC2_ACCESS_KEY'] || load_keys_from_file[:access_key] || load_keys_from_credential_file[:access_key]
|
18
20
|
end
|
19
|
-
|
21
|
+
|
20
22
|
def self.default_secret_access_key
|
21
23
|
ENV['EC2_SECRET_KEY'] || load_keys_from_file[:secret_access_key] || load_keys_from_credential_file[:secret_access_key]
|
22
24
|
end
|
23
|
-
|
25
|
+
|
24
26
|
def self.default_private_key
|
25
27
|
ENV['EC2_PRIVATE_KEY'] || load_keys_from_file[:private_key]
|
26
28
|
end
|
27
|
-
|
29
|
+
|
28
30
|
def self.default_cert
|
29
31
|
ENV['EC2_CERT'] || load_keys_from_file[:cert]
|
30
32
|
end
|
31
|
-
|
33
|
+
|
32
34
|
def self.default_user_id
|
33
35
|
ENV['EC2_USER_ID'] || load_keys_from_file[:user_id]
|
34
36
|
end
|
35
|
-
|
37
|
+
|
36
38
|
def self.default_ec2_url
|
37
39
|
ENV['EC2_URL'] || load_keys_from_file[:ec2_url]
|
38
40
|
end
|
39
|
-
|
41
|
+
|
40
42
|
def self.default_s3_url
|
41
43
|
ENV['S3_URL'] || load_keys_from_file[:s3_url]
|
42
44
|
end
|
43
|
-
|
45
|
+
|
44
46
|
def self.default_cloud_cert
|
45
47
|
ENV['CLOUD_CERT'] || ENV['EUCALYPTUS_CERT'] || load_keys_from_file[:cloud_cert]
|
46
48
|
end
|
@@ -48,7 +50,7 @@ module CloudProviders
|
|
48
50
|
def self.default_credential_file
|
49
51
|
ENV['AWS_CREDENTIAL_FILE'] || load_keys_from_file[:credential_file]
|
50
52
|
end
|
51
|
-
|
53
|
+
|
52
54
|
# Load the yaml file containing keys. If the file does not exist, return an empty hash
|
53
55
|
def self.load_keys_from_file(filename="#{ENV["HOME"]}/.poolparty/aws", caching=true)
|
54
56
|
return @aws_yml if @aws_yml && caching==true
|
@@ -71,8 +73,8 @@ module CloudProviders
|
|
71
73
|
}
|
72
74
|
return {:access_key => @access_key, :secret_access_key => @secret_access_key}
|
73
75
|
end
|
74
|
-
|
75
|
-
|
76
|
+
|
77
|
+
|
76
78
|
default_options(
|
77
79
|
:instance_type => 'm1.small',
|
78
80
|
:availability_zones => ["us-east-1a"],
|
@@ -84,7 +86,7 @@ module CloudProviders
|
|
84
86
|
:secret_access_key => default_secret_access_key,
|
85
87
|
:ec2_url => default_ec2_url,
|
86
88
|
:s3_url => default_s3_url,
|
87
|
-
:credential_file
|
89
|
+
:credential_file => default_credential_file,
|
88
90
|
:min_count => 1,
|
89
91
|
:max_count => 1,
|
90
92
|
:user_data => '',
|
@@ -109,6 +111,7 @@ module CloudProviders
|
|
109
111
|
puts " maximum_instances: #{maximum_instances}"
|
110
112
|
puts " security_groups: #{security_group_names.join(", ")}"
|
111
113
|
puts " using keypair: #{keypair}"
|
114
|
+
puts " with user_data #{user_data.to_s[0..100]}"
|
112
115
|
puts " user: #{user}\n"
|
113
116
|
|
114
117
|
security_groups.each do |sg|
|
@@ -152,7 +155,7 @@ module CloudProviders
|
|
152
155
|
puts " autoscaler: #{a.name}"
|
153
156
|
puts "-----> The autoscaling groups will launch the instances"
|
154
157
|
a.run
|
155
|
-
|
158
|
+
|
156
159
|
progress_bar_until("Waiting for autoscaler to launch instances") do
|
157
160
|
reset!
|
158
161
|
running_nodes = nodes.select {|n| n.running? }
|
@@ -161,8 +164,8 @@ module CloudProviders
|
|
161
164
|
reset!
|
162
165
|
end
|
163
166
|
end
|
164
|
-
|
165
|
-
from_ports = security_groups.map {|a| a.authorizes.map {|t| t.from_port.to_i }.flatten }.flatten
|
167
|
+
|
168
|
+
from_ports = security_groups.map {|a| a.authorizes.map {|t| t.from_port.to_i }.flatten }.flatten
|
166
169
|
if from_ports.include?(22)
|
167
170
|
progress_bar_until("Waiting for the instances to be accessible by ssh") do
|
168
171
|
running_nodes = nodes.select {|n| n.running? }
|
@@ -172,20 +175,20 @@ module CloudProviders
|
|
172
175
|
accessible_count == running_nodes.size
|
173
176
|
end
|
174
177
|
end
|
175
|
-
|
178
|
+
|
176
179
|
assign_elastic_ips
|
177
180
|
cleanup_ssh_known_hosts!
|
178
181
|
puts "Attaching EBS volumes"
|
179
182
|
assign_ebs_volumes # Assign EBS volumes
|
180
183
|
end
|
181
|
-
|
184
|
+
|
182
185
|
def teardown
|
183
186
|
puts "------ Tearing down and cleaning up #{cloud.name} cloud"
|
184
187
|
unless autoscalers.empty?
|
185
188
|
puts "Tearing down autoscalers"
|
186
189
|
end
|
187
190
|
end
|
188
|
-
|
191
|
+
|
189
192
|
def expand_by(num=1)
|
190
193
|
e = Ec2Instance.run!({
|
191
194
|
:image_id => image_id,
|
@@ -208,7 +211,7 @@ module CloudProviders
|
|
208
211
|
end
|
209
212
|
all_nodes.detect {|n| n.instance_id == e.instance_id }
|
210
213
|
end
|
211
|
-
|
214
|
+
|
212
215
|
def decoded_user_data
|
213
216
|
if user_data
|
214
217
|
if File.file?(user_data)
|
@@ -218,13 +221,13 @@ module CloudProviders
|
|
218
221
|
end
|
219
222
|
end
|
220
223
|
end
|
221
|
-
|
224
|
+
|
222
225
|
def wait_for_node(instance)
|
223
226
|
reset!
|
224
227
|
inst = all_nodes.detect {|n| n.instance_id == instance.instance_id }
|
225
228
|
inst.running? if inst
|
226
229
|
end
|
227
|
-
|
230
|
+
|
228
231
|
def contract_by(num=1)
|
229
232
|
raise RuntimeError, "Contracting instances by #{num} will lower the number of instances below specified minimum" unless nodes.size - num > minimum_instances
|
230
233
|
num.times do |i|
|
@@ -235,9 +238,9 @@ module CloudProviders
|
|
235
238
|
end
|
236
239
|
reset!
|
237
240
|
end
|
238
|
-
|
241
|
+
|
239
242
|
def bootstrap_nodes!(tmp_path=nil)
|
240
|
-
unless security_groups.map {|a| a.authorizes.map {|t| t.from_port.to_i }.flatten }.flatten.include?(22)
|
243
|
+
unless security_groups.map {|a| a.authorizes.map {|t| t.from_port.to_i }.flatten }.flatten.include?(22)
|
241
244
|
warn "Cloud security_groups are not authorized for ssh. Cannot bootstrap."
|
242
245
|
return
|
243
246
|
end
|
@@ -250,18 +253,18 @@ module CloudProviders
|
|
250
253
|
node.run_chef!
|
251
254
|
end
|
252
255
|
end
|
253
|
-
|
256
|
+
|
254
257
|
def configure_nodes!(tmp_path=nil)
|
255
258
|
# removed duplicated code (now configure_nodes! invokes
|
256
259
|
# node.bootstrap_chef!, while old version did not, but I believe
|
257
260
|
# this is harmless)
|
258
|
-
bootstrap_nodes!(tmp_path)
|
261
|
+
bootstrap_nodes!(tmp_path)
|
259
262
|
|
260
263
|
ebs_volume_groups.each do |vol_grp|
|
261
264
|
vol_grp.verify_attachments nodes
|
262
265
|
end
|
263
266
|
end
|
264
|
-
|
267
|
+
|
265
268
|
def assign_elastic_ips
|
266
269
|
unless elastic_ips.empty?
|
267
270
|
unused_elastic_ip_addresses = ElasticIp.unused_elastic_ips(self).map {|i| i.public_ip }
|
@@ -299,11 +302,27 @@ module CloudProviders
|
|
299
302
|
def nodes
|
300
303
|
all_nodes.select {|i| i.in_service? }#describe_instances.select {|i| i.in_service? && security_groups.include?(i.security_groups) }
|
301
304
|
end
|
302
|
-
|
305
|
+
|
306
|
+
# === Description
|
307
|
+
#
|
308
|
+
# Return all the security groups of the instance that are prefixed with #poolparty.
|
309
|
+
#
|
310
|
+
# These are special security groups used only for tagging
|
311
|
+
#
|
312
|
+
# === Parameters
|
313
|
+
# instance - An ec2 instance as returned from describe_instances
|
314
|
+
def tags instance
|
315
|
+
instance.groupSet.item.collect{|g| g.groupId }.select {|s| s.start_with? "#poolparty"}
|
316
|
+
end
|
317
|
+
|
303
318
|
def all_nodes
|
304
|
-
@nodes ||= describe_instances.select {|i|
|
319
|
+
@nodes ||= describe_instances.select { |i|
|
320
|
+
!(security_group_names & tags(i)).empty?
|
321
|
+
}.sort {|a,b|
|
322
|
+
DateTime.parse(a.launchTime) <=> DateTime.parse(b.launchTime)
|
323
|
+
}
|
305
324
|
end
|
306
|
-
|
325
|
+
|
307
326
|
# Describe instances
|
308
327
|
# Describe the instances that are available on this cloud
|
309
328
|
# @params id (optional) if present, details about the instance
|
@@ -318,15 +337,15 @@ module CloudProviders
|
|
318
337
|
end
|
319
338
|
end.flatten
|
320
339
|
rescue AWS::InvalidClientTokenId => e # AWS credentials invalid
|
321
|
-
|
322
|
-
|
340
|
+
puts "Error contacting AWS: #{e}"
|
341
|
+
raise e
|
323
342
|
rescue Exception => e
|
324
343
|
[]
|
325
344
|
end
|
326
345
|
end
|
327
|
-
|
346
|
+
|
328
347
|
# Extras!
|
329
|
-
|
348
|
+
|
330
349
|
def block_device_mapping(o=[], given_name=cloud.proper_name )
|
331
350
|
@mappings ||= o
|
332
351
|
end
|
@@ -357,10 +376,10 @@ module CloudProviders
|
|
357
376
|
@ec2 ||= begin
|
358
377
|
AWS::EC2::Base.new( :access_key_id => access_key, :secret_access_key => secret_access_key )
|
359
378
|
rescue AWS::ArgumentError => e # AWS credentials missing?
|
360
|
-
|
361
|
-
|
379
|
+
puts "Error contacting AWS: #{e}"
|
380
|
+
raise e
|
362
381
|
rescue Exception => e
|
363
|
-
|
382
|
+
puts "Generic error #{e.class}: #{e}"
|
364
383
|
end
|
365
384
|
end
|
366
385
|
|
@@ -398,7 +417,7 @@ module CloudProviders
|
|
398
417
|
@ebs_volume_groups ||= []
|
399
418
|
end
|
400
419
|
|
401
|
-
# dsl method for EBS volumes. E.G.:
|
420
|
+
# dsl method for EBS volumes. E.G.:
|
402
421
|
# ebs_volumes do
|
403
422
|
# volumes "vol-001248ff", "vol-01ff4b85" # use existing volumes, not mandatory
|
404
423
|
# device "/dev/sdf"
|
@@ -412,7 +431,7 @@ module CloudProviders
|
|
412
431
|
def assign_ebs_volumes
|
413
432
|
ebs_volume_groups.each{|ebs_volume_group| ebs_volume_group.attach(nodes)}
|
414
433
|
end
|
415
|
-
|
434
|
+
|
416
435
|
def rds_instances
|
417
436
|
@rds_instances ||= []
|
418
437
|
end
|
@@ -447,13 +466,13 @@ module CloudProviders
|
|
447
466
|
# Read credentials from credential_file if one exists
|
448
467
|
def credential_file(file=nil)
|
449
468
|
unless file.nil?
|
450
|
-
dsl_options[:credential_file]=file
|
469
|
+
dsl_options[:credential_file]=file
|
451
470
|
dsl_options.merge!(Ec2.load_keys_from_credential_file(file))
|
452
471
|
else
|
453
472
|
fetch(:credential_file)
|
454
473
|
end
|
455
474
|
end
|
456
|
-
|
475
|
+
|
457
476
|
private
|
458
477
|
# Helper to get the options with self as parent
|
459
478
|
def sub_opts
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module CloudProviders
|
2
2
|
class Ec2Instance < RemoteInstance
|
3
|
-
|
3
|
+
|
4
4
|
default_options(
|
5
5
|
:security_groups => [],
|
6
6
|
:private_ip => nil,
|
@@ -15,35 +15,41 @@ module CloudProviders
|
|
15
15
|
:instance_initiated_shutdown_behavior => nil,
|
16
16
|
:subnet_id => nil
|
17
17
|
)
|
18
|
-
|
18
|
+
|
19
19
|
def initialize(raw_response={})
|
20
20
|
@raw_response = raw_response
|
21
|
-
self.instance_id
|
22
|
-
self.security_groups
|
23
|
-
self.image_id
|
24
|
-
self.private_ip
|
25
|
-
self.dns_name
|
26
|
-
self.instance_type
|
27
|
-
self.public_ip
|
28
|
-
self.key_name
|
29
|
-
self.launch_time
|
30
|
-
self.availability_zones
|
31
|
-
self.status
|
32
|
-
self.block_device_mapping
|
33
|
-
self.
|
34
|
-
|
35
|
-
self.
|
21
|
+
self.instance_id = raw_response["instanceId"] rescue nil
|
22
|
+
self.security_groups = raw_response.groupSet.item.map{|sg| sg.groupId }.sort rescue nil
|
23
|
+
self.image_id = raw_response["imageId"] rescue nil
|
24
|
+
self.private_ip = raw_response["privateIpAddress"] rescue nil
|
25
|
+
self.dns_name = raw_response["dnsName"] rescue nil
|
26
|
+
self.instance_type = raw_response["instanceType"] rescue nil
|
27
|
+
self.public_ip = raw_response["ipAddress"] rescue nil
|
28
|
+
self.key_name = raw_response["keyName"] rescue nil
|
29
|
+
self.launch_time = raw_response["launchTime"] rescue nil
|
30
|
+
self.availability_zones = raw_response["placement"]["availabilityZone"] rescue nil
|
31
|
+
self.status = raw_response["instanceState"]["name"] rescue nil
|
32
|
+
self.block_device_mapping = raw_response["blockDeviceMapping"] rescue nil
|
33
|
+
self.subnet_id = raw_response["subnetId"] rescue nil
|
34
|
+
# disable_api_termination and instance_initiated_shutdown_behavior don't currently get returned in the request -- you'd need to later call describe_instance_attribute
|
35
|
+
self.disable_api_termination = raw_response["disableApiTermination"] rescue nil
|
36
|
+
self.instance_initiated_shutdown_behavior = raw_response["instanceInitiatedShutdownBehavior"] rescue nil
|
36
37
|
super
|
37
38
|
end
|
38
|
-
|
39
|
+
|
39
40
|
def keypair(n=nil)
|
40
|
-
@keypair
|
41
|
+
return @keypair if @keypair
|
42
|
+
@keypair = (cloud.keypair.basename == self.key_name) ? cloud.keypair : Keypair.new(self.key_name, cloud.keypair.extra_paths)
|
41
43
|
end
|
42
|
-
|
44
|
+
|
45
|
+
def security_group_names
|
46
|
+
security_groups.map{|a| a.to_s }
|
47
|
+
end
|
48
|
+
|
43
49
|
def zone
|
44
50
|
availability_zones.first
|
45
51
|
end
|
46
|
-
|
52
|
+
|
47
53
|
def reachable?
|
48
54
|
ping_port self.public_ip, 22
|
49
55
|
end
|
@@ -56,38 +62,42 @@ module CloudProviders
|
|
56
62
|
in_service? and
|
57
63
|
keypair and keypair.exists?
|
58
64
|
end
|
59
|
-
|
65
|
+
|
60
66
|
def in_service?
|
61
67
|
running?
|
62
68
|
end
|
63
|
-
|
69
|
+
|
64
70
|
def run!
|
65
|
-
r = cloud_provider.ec2.run_instances(
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
71
|
+
r = cloud_provider.ec2.run_instances(
|
72
|
+
:image_id => image_id,
|
73
|
+
:min_count => min_count,
|
74
|
+
:max_count => max_count,
|
75
|
+
:key_name => keypair.basename,
|
76
|
+
:security_group => cloud.security_group_names,
|
77
|
+
:user_data => user_data,
|
78
|
+
:instance_type => instance_type,
|
79
|
+
:availability_zone => availability_zone,
|
80
|
+
:block_device_mapping => block_device_mapping,
|
81
|
+
:disable_api_termination => disable_api_termination,
|
82
|
+
:instance_initiated_shutdown_behavior => instance_initiated_shutdown_behavior,
|
83
|
+
:base64_encoded => true)
|
75
84
|
r.instancesSet.item.map do |i|
|
76
85
|
inst_options = i.merge(r.merge(:cloud => cloud)).merge(cloud.cloud_provider.dsl_options)
|
77
86
|
Ec2Instance.new(inst_options)
|
78
87
|
end.first
|
79
88
|
end
|
80
89
|
def self.run!(hsh); new(hsh).run!; end
|
81
|
-
|
90
|
+
|
82
91
|
def terminate!
|
83
92
|
cloud_provider.ec2.terminate_instances(:instance_id => [self.instance_id])
|
84
93
|
cloud_provider.reset!
|
85
94
|
end
|
86
95
|
def self.terminate!(hsh={}); new(hsh).terminate!; end
|
87
|
-
|
96
|
+
|
88
97
|
# list of directories and files to exclude when bundling an instance
|
89
98
|
def rsync_excludes(array_of_abs_paths_to_exclude=nil)
|
90
|
-
array_of_abs_paths_to_exclude ||= %w
|
99
|
+
array_of_abs_paths_to_exclude ||= %w[
|
100
|
+
/sys
|
91
101
|
/proc
|
92
102
|
/dev/pts
|
93
103
|
/dev
|
@@ -99,8 +109,8 @@ module CloudProviders
|
|
99
109
|
/etc/ssh/moduli
|
100
110
|
/etc/udev/rules.d/70-persistent-net.rules
|
101
111
|
/etc/udev/rules.d/z25_persistent-net.rules
|
102
|
-
|
103
|
-
array_of_abs_paths_to_exclude.inject(''){|str, path| str<<"--exclude=#{path}"; str}
|
112
|
+
]
|
113
|
+
array_of_abs_paths_to_exclude.inject(''){|str, path| str << "--exclude=#{path}" ; str}
|
104
114
|
end
|
105
115
|
|
106
116
|
# create an image file and copy this instance to the image file.
|
@@ -138,7 +148,7 @@ module CloudProviders
|
|
138
148
|
scp ec2cert, "/mnt/bundle/"
|
139
149
|
scp cert, "/mnt/bundle/"
|
140
150
|
arch = self[:instanceType].match(/m1\.small|c1\.medium/) ? 'i386' : 'x86_64'
|
141
|
-
image = img ? img : make_image(opts)
|
151
|
+
image = img ? img : make_image(opts)
|
142
152
|
ssh "ec2-bundle-image #{image} -d /mnt/bundle -u #{self[:ownerId]} -k /mnt/bundle/pk-*.pem -c /tmp/cert-*.pem"
|
143
153
|
manifest = "/mnt/bundle/#{opts[:prefix]}.manifest.xml"
|
144
154
|
ssh "ec2-upload-bundle -a #{access_key} -s #{secret_access_key} -m #{manifest}"
|
@@ -146,6 +156,6 @@ module CloudProviders
|
|
146
156
|
ami = ami_str.grep(/ami-\w*/).first
|
147
157
|
return ami
|
148
158
|
end
|
149
|
-
|
159
|
+
|
150
160
|
end
|
151
161
|
end
|