poolparty 1.4.4 → 1.4.5
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/README.rdoc +3 -1
- data/VERSION.yml +1 -1
- data/examples/simple.rb +3 -1
- data/lib/cloud_providers/ec2/ec2.rb +9 -8
- data/lib/cloud_providers/ec2/helpers/elastic_auto_scaler.rb +124 -1
- data/lib/cloud_providers/remote_instance.rb +1 -1
- data/vendor/gems/amazon-ec2/lib/AWS/Autoscaling/autoscaling.rb +1 -1
- metadata +1 -1
data/README.rdoc
CHANGED
|
@@ -21,7 +21,9 @@ For instance, to start a basic cloud, let's write one:
|
|
|
21
21
|
cloud "app" do
|
|
22
22
|
instances 2..10
|
|
23
23
|
using :ec2
|
|
24
|
-
|
|
24
|
+
autoscale do
|
|
25
|
+
trigger :lower_threshold => 0.3, :upper_threshold => 1.0, :measure => :cpu
|
|
26
|
+
end
|
|
25
27
|
security_group do
|
|
26
28
|
authorize :from_port => 22, :to_port => 22
|
|
27
29
|
end
|
data/VERSION.yml
CHANGED
data/examples/simple.rb
CHANGED
|
@@ -8,7 +8,9 @@ pool "poolparty" do
|
|
|
8
8
|
cloud "simple" do
|
|
9
9
|
instances 1..3
|
|
10
10
|
using :ec2
|
|
11
|
-
autoscale
|
|
11
|
+
autoscale do
|
|
12
|
+
trigger :lower_threshold => 0.3, :upper_threshold => 1.0, :measure => :cpu
|
|
13
|
+
end
|
|
12
14
|
image_id "ami-ccf615a5" #alestic jaunty
|
|
13
15
|
availability_zones ['us-east-1b']
|
|
14
16
|
#TODO: accept array of hashes defining security group rules
|
|
@@ -87,7 +87,8 @@ module CloudProviders
|
|
|
87
87
|
puts " minimum_instances: #{minimum_instances}"
|
|
88
88
|
puts " maximum_instances: #{maximum_instances}"
|
|
89
89
|
puts " security_groups: #{security_group_names.join(", ")}"
|
|
90
|
-
puts "
|
|
90
|
+
puts " using keypair: #{keypair}"
|
|
91
|
+
puts " user: #{user}\n"
|
|
91
92
|
|
|
92
93
|
security_groups.each do |sg|
|
|
93
94
|
sg.run
|
|
@@ -98,19 +99,19 @@ module CloudProviders
|
|
|
98
99
|
puts " load balancer: #{lb.name}"
|
|
99
100
|
lb.run
|
|
100
101
|
end
|
|
101
|
-
end
|
|
102
|
-
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
if autoscalers.empty? # not using autoscaling
|
|
103
105
|
puts "---- live, running instances (#{nodes.size}) ----"
|
|
104
106
|
if nodes.size < minimum_instances
|
|
105
107
|
expansion_count = minimum_instances - nodes.size
|
|
106
|
-
puts "-----> expanding the cloud because the minimum_instances is not satisified:
|
|
108
|
+
puts "-----> expanding the cloud because the #{expansion_count} minimum_instances is not satisified: "
|
|
107
109
|
expand_by(expansion_count)
|
|
108
110
|
elsif nodes.size > maximum_instances
|
|
109
111
|
contraction_count = nodes.size - maximum_instances
|
|
110
|
-
puts "-----> contracting the cloud because the instances count exceeds the maximum_instances by #{contraction_count}"
|
|
112
|
+
puts "-----> contracting the cloud because the instances count exceeds the #{maximum_instances} maximum_instances by #{contraction_count}"
|
|
111
113
|
contract_by(contraction_count)
|
|
112
114
|
end
|
|
113
|
-
|
|
114
115
|
progress_bar_until("Waiting for the instances to be launched") do
|
|
115
116
|
reset!
|
|
116
117
|
running_nodes = nodes.select {|n| n.running? }
|
|
@@ -170,12 +171,12 @@ module CloudProviders
|
|
|
170
171
|
progress_bar_until("Waiting for node to launch...") do
|
|
171
172
|
wait_for_node(e)
|
|
172
173
|
end
|
|
173
|
-
all_nodes.
|
|
174
|
+
all_nodes.detect {|n| n.instance_id == e.instance_id }
|
|
174
175
|
end
|
|
175
176
|
|
|
176
177
|
def wait_for_node(instance)
|
|
177
178
|
reset!
|
|
178
|
-
inst = all_nodes.
|
|
179
|
+
inst = all_nodes.detect {|n| n.instance_id == instance.instance_id }
|
|
179
180
|
inst.running?
|
|
180
181
|
end
|
|
181
182
|
|
|
@@ -21,12 +21,18 @@ module CloudProviders
|
|
|
21
21
|
puts "Deleting old launch configuration: #{old_launch_configuration_name}"
|
|
22
22
|
as.delete_launch_configuration(:launch_configuration_name => old_launch_configuration_name)
|
|
23
23
|
end
|
|
24
|
-
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
triggers.each do |trigger|
|
|
27
|
+
trigger.run
|
|
25
28
|
end
|
|
26
29
|
end
|
|
27
30
|
|
|
28
31
|
# First, change the min_count to
|
|
29
32
|
def teardown
|
|
33
|
+
triggers.each do |trigger|
|
|
34
|
+
trigger.teardown
|
|
35
|
+
end
|
|
30
36
|
if autoscaling_groups.select {|n| n.name == name }.empty?
|
|
31
37
|
puts "Cloud #{cloud.name} autoscaling group does not exist"
|
|
32
38
|
else
|
|
@@ -292,7 +298,16 @@ module CloudProviders
|
|
|
292
298
|
describe_autoscaling_groups.DescribeAutoScalingGroupsResult.AutoScalingGroups.member
|
|
293
299
|
end
|
|
294
300
|
|
|
301
|
+
def trigger(*trigger_hashes)
|
|
302
|
+
trigger_hashes.each do |hsh, blk|
|
|
303
|
+
triggers << ElasticTrigger.new(name, hsh.merge(:cloud => cloud), &blk)
|
|
304
|
+
end
|
|
305
|
+
end
|
|
306
|
+
|
|
295
307
|
private
|
|
308
|
+
def triggers
|
|
309
|
+
@triggers ||= []
|
|
310
|
+
end
|
|
296
311
|
def reset!
|
|
297
312
|
@old_auto_scaling_group_name =
|
|
298
313
|
@new_auto_scaling_group_name =
|
|
@@ -301,4 +316,112 @@ module CloudProviders
|
|
|
301
316
|
cloud.reset!
|
|
302
317
|
end
|
|
303
318
|
end
|
|
319
|
+
class ElasticTrigger < Ec2Helper
|
|
320
|
+
default_options(
|
|
321
|
+
:measure => :cpu,
|
|
322
|
+
:period => 60,
|
|
323
|
+
:statistic => :average,
|
|
324
|
+
:unit => "Seconds",
|
|
325
|
+
:lower_threshold => 20,
|
|
326
|
+
:upper_threshold => 60,
|
|
327
|
+
:trigger_name => "CpuTrigger",
|
|
328
|
+
:lower_breach_scale_increment => -1,
|
|
329
|
+
:upper_breach_scale_increment => 1,
|
|
330
|
+
:breach_duration => 120
|
|
331
|
+
)
|
|
332
|
+
|
|
333
|
+
def measure_names
|
|
334
|
+
{:cpu => "CPUUtilization"}
|
|
335
|
+
end
|
|
336
|
+
|
|
337
|
+
def statistic_names
|
|
338
|
+
{:min => "Minimum", :max => "Maximum", :average => "Average", :sum => "Sum"}
|
|
339
|
+
end
|
|
340
|
+
|
|
341
|
+
def run
|
|
342
|
+
if autoscaling_triggers.empty?
|
|
343
|
+
create_autoscaling_trigger!
|
|
344
|
+
else
|
|
345
|
+
t = autoscaling_triggers.map do |hsh|
|
|
346
|
+
diff(hsh)
|
|
347
|
+
end.flatten
|
|
348
|
+
unless t.empty?
|
|
349
|
+
puts "Creating or updating trigger: #{trigger_name}"
|
|
350
|
+
create_autoscaling_trigger!
|
|
351
|
+
end
|
|
352
|
+
end
|
|
353
|
+
end
|
|
354
|
+
|
|
355
|
+
def teardown
|
|
356
|
+
autoscaling_triggers.each do |trigger|
|
|
357
|
+
puts "Deleting trigger: #{trigger[:trigger_name]}"
|
|
358
|
+
as.delete_trigger(:trigger_name => trigger[:trigger_name], :autoscaling_group_name => name)
|
|
359
|
+
end
|
|
360
|
+
end
|
|
361
|
+
|
|
362
|
+
def diff(hsh={})
|
|
363
|
+
[ :measure_name,
|
|
364
|
+
:period,
|
|
365
|
+
:statistic,
|
|
366
|
+
:lower_threshold,
|
|
367
|
+
:lower_breach_scale_increment,
|
|
368
|
+
:upper_threshold,
|
|
369
|
+
:upper_breach_scale_increment,
|
|
370
|
+
:unit,
|
|
371
|
+
:trigger_name].reject do |k|
|
|
372
|
+
hsh[k].to_s.capitalize == self.send(k).to_s.capitalize
|
|
373
|
+
end
|
|
374
|
+
end
|
|
375
|
+
|
|
376
|
+
private
|
|
377
|
+
|
|
378
|
+
def autoscaling_triggers
|
|
379
|
+
begin
|
|
380
|
+
as.describe_triggers(:autoscaling_group_name => name).DescribeTriggersResult.Triggers.member.map do |trigger|
|
|
381
|
+
{
|
|
382
|
+
:trigger_name => trigger["TriggerName"],
|
|
383
|
+
:statistic => trigger["Statistic"],
|
|
384
|
+
:status => trigger["Status"],
|
|
385
|
+
:lower_threshold => trigger["LowerThreshold"],
|
|
386
|
+
:created_time => trigger["CreatedTime"],
|
|
387
|
+
:measure_name => trigger["MeasureName"],
|
|
388
|
+
:upper_threshold => trigger["UpperThreshold"],
|
|
389
|
+
:lower_breach_scale_increment => trigger["LowerBreachScaleIncrement"],
|
|
390
|
+
:period => trigger["Period"],
|
|
391
|
+
:upper_breach_scale_increment => trigger["UpperBreachScaleIncrement"],
|
|
392
|
+
:breach_duration => trigger["BreachDuration"],
|
|
393
|
+
:dimensions => trigger["Dimensions"],
|
|
394
|
+
:unit => trigger["Unit"],
|
|
395
|
+
:autoscaling_group_name => trigger["AutoScalingGroupName"]
|
|
396
|
+
}
|
|
397
|
+
end
|
|
398
|
+
rescue Exception => e
|
|
399
|
+
[]
|
|
400
|
+
end
|
|
401
|
+
end
|
|
402
|
+
def create_autoscaling_trigger!
|
|
403
|
+
as.create_or_updated_scaling_trigger(
|
|
404
|
+
:autoscaling_group_name => name,
|
|
405
|
+
:dimensions => {:name => "AutoScalingGroupName", :value => name},
|
|
406
|
+
:measure_name => measure_name,
|
|
407
|
+
:period => "#{period}",
|
|
408
|
+
:trigger_name => trigger_name,
|
|
409
|
+
:statistic => (statistic_names[statistic] || statistic),
|
|
410
|
+
:unit => unit,
|
|
411
|
+
:breach_duration => breach_duration,
|
|
412
|
+
:lower_threshold => "#{lower_threshold}",
|
|
413
|
+
:lower_breach_scale_increment => "#{lower_breach_scale_increment}",
|
|
414
|
+
:upper_threshold => "#{upper_threshold}",
|
|
415
|
+
:upper_breach_scale_increment => "#{upper_breach_scale_increment}"
|
|
416
|
+
)
|
|
417
|
+
end
|
|
418
|
+
|
|
419
|
+
def measure_name
|
|
420
|
+
measure_names[measure] || measure
|
|
421
|
+
end
|
|
422
|
+
|
|
423
|
+
def trigger_name
|
|
424
|
+
"#{(measure_names[measure] || measure)}-#{name}" || name
|
|
425
|
+
end
|
|
426
|
+
end
|
|
304
427
|
end
|
|
@@ -112,7 +112,7 @@ module AWS
|
|
|
112
112
|
params["Dimensions.member.1.Name"] = options[:dimensions][:name]
|
|
113
113
|
params["Dimensions.member.1.Value"] = options[:dimensions][:value]
|
|
114
114
|
else
|
|
115
|
-
raise ArgumentError, "
|
|
115
|
+
raise ArgumentError, "Dimensions must be either an array or a hash"
|
|
116
116
|
end
|
|
117
117
|
params['MeasureName'] = options[:measure_name]
|
|
118
118
|
params['Statistic'] = options[:statistic]
|