rubber 2.1.2 → 2.2.0
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/.travis.yml +2 -4
- data/CHANGELOG +98 -0
- data/LICENSE +10 -336
- data/lib/rubber/cloud/aws.rb +8 -8
- data/lib/rubber/commands/cron.rb +1 -1
- data/lib/rubber/commands/util.rb +46 -0
- data/lib/rubber/encryption.rb +46 -0
- data/lib/rubber/environment.rb +24 -5
- data/lib/rubber/recipes/rubber.rb +1 -1
- data/lib/rubber/recipes/rubber/instances.rb +97 -37
- data/lib/rubber/recipes/rubber/setup.rb +9 -4
- data/lib/rubber/recipes/rubber/static_ips.rb +3 -2
- data/lib/rubber/version.rb +1 -1
- data/rubber.gemspec +1 -2
- data/templates/apache/config/rubber/rubber-apache.yml +2 -2
- data/templates/base/config/deploy.rb +1 -1
- data/templates/base/config/rubber/common/crontab +1 -3
- data/templates/base/config/rubber/common/gemrc +5 -0
- data/templates/base/config/rubber/common/rubber.profile +0 -3
- data/templates/base/config/rubber/common/ruby.profile +9 -0
- data/templates/base/config/rubber/deploy-setup.rb +45 -65
- data/templates/base/config/rubber/rubber-ruby.yml +21 -0
- data/templates/base/config/rubber/rubber.yml +8 -3
- data/templates/base/script/rubber +7 -3
- data/templates/collectd/config/rubber/role/passenger/collectd-passenger.rb.conf +2 -2
- data/templates/collectd/config/rubber/role/passenger/passenger-status-sudoers.conf +2 -2
- data/templates/complete_unicorn_nginx/config/rubber/rubber-complete.yml +2 -3
- data/templates/complete_unicorn_nginx/templates.yml +0 -1
- data/templates/elasticsearch/config/rubber/deploy-elasticsearch.rb +1 -1
- data/templates/elasticsearch/config/rubber/rubber-elasticsearch.yml +1 -1
- data/templates/graphite/config/rubber/deploy-graphite.rb +9 -52
- data/templates/graphite/config/rubber/role/graphite_server/carbon.conf +1 -1
- data/templates/graphite/config/rubber/role/graphite_server/graphite-collectd-ping.conf +11 -0
- data/templates/graphite/config/rubber/role/graphite_server/monit-graphite_server.conf +8 -0
- data/templates/graphite/config/rubber/role/graphite_web/graphite_web-upstart.conf +15 -0
- data/templates/graphite/config/rubber/role/graphite_web/monit-graphite_web.conf +7 -0
- data/templates/graphite/config/rubber/role/graphite_web/uwsgi.ini +16 -0
- data/templates/graphite/config/rubber/rubber-graphite.yml +6 -4
- data/templates/graphite/templates.yml +2 -0
- data/templates/mongrel/config/rubber/deploy-mongrel.rb +1 -1
- data/templates/monit/config/rubber/role/mongrel/monit-mongrel.conf +2 -2
- data/templates/munin/config/rubber/role/munin/munin-plugins.conf +3 -3
- data/templates/munin/config/rubber/role/passenger/munin-passenger-memory.conf +1 -1
- data/templates/munin/config/rubber/role/passenger/munin-passenger-sudoers.conf +2 -2
- data/templates/munin/config/rubber/role/passenger/munin-passenger.conf +1 -1
- data/templates/munin/config/rubber/role/passenger_nginx/munin-passenger-memory.conf +1 -1
- data/templates/munin/config/rubber/role/passenger_nginx/munin-passenger-sudoers.conf +2 -2
- data/templates/munin/config/rubber/role/passenger_nginx/munin-passenger.conf +1 -1
- data/templates/passenger/config/rubber/deploy-passenger.rb +5 -11
- data/templates/passenger/config/rubber/role/passenger/passenger-apache-vhost.conf +12 -0
- data/templates/passenger/config/rubber/rubber-passenger.yml +3 -3
- data/templates/passenger_nginx/config/rubber/role/passenger_nginx/nginx.conf +1 -1
- data/templates/passenger_nginx/config/rubber/rubber-passenger_nginx.yml +2 -2
- data/templates/postgresql/config/rubber/deploy-postgresql.rb +47 -0
- data/templates/redis/config/rubber/rubber-redis.yml +1 -1
- data/templates/resque/templates.yml +0 -1
- data/templates/sidekiq/config/rubber/deploy-sidekiq.rb +35 -0
- data/templates/sidekiq/config/rubber/role/sidekiq/monit-sidekiq.conf +10 -0
- data/templates/sidekiq/config/rubber/rubber-sidekiq.yml +2 -0
- data/templates/sidekiq/templates.rb +2 -0
- data/templates/sidekiq/templates.yml +4 -0
- data/templates/solr/config/rubber/common/solr_sunspot.yml +10 -0
- data/templates/solr/config/rubber/deploy-solr.rb +78 -0
- data/templates/solr/config/rubber/rubber-solr.yml +10 -0
- data/templates/solr/templates.yml +3 -0
- data/templates/sphinx/config/rubber/deploy-sphinx.rb +4 -4
- data/templates/torquebox/config/rubber/deploy-torquebox.rb +16 -4
- data/templates/torquebox/config/rubber/role/app/torquebox-apache-vhost.conf +15 -5
- data/templates/torquebox/config/rubber/role/torquebox/graylog-logging-module.xml +9 -0
- data/templates/torquebox/config/rubber/role/torquebox/standalone-ha.xml +25 -7
- data/templates/torquebox/config/rubber/role/torquebox/standalone.conf +2 -2
- data/templates/torquebox/config/rubber/rubber-torquebox.yml +6 -3
- data/templates/zookeeper/config/rubber/rubber-zookeeper.yml +1 -1
- data/test/command_test.rb +7 -5
- data/test/commands/cron_test.rb +22 -18
- data/test/commands/util_test.rb +40 -0
- data/test/encryption_test.rb +59 -0
- data/test/environment_test.rb +14 -0
- data/test/fixtures/obfuscated/rubber.yml +3 -0
- data/test/fixtures/obfuscated/secret.yml +1 -0
- metadata +33 -12
- data/templates/base/config/rubber/rubber-rvm.yml +0 -42
- data/templates/complete_passenger/templates.rb +0 -9
- data/templates/complete_passenger_nginx/templates.rb +0 -8
- data/templates/complete_unicorn_nginx/config/rubber/role/haproxy/haproxy-unicorn.conf +0 -21
- data/templates/complete_unicorn_nginx/templates.rb +0 -8
- data/templates/graphite/config/rubber/role/graphite_web/graphite-vhost.conf +0 -62
data/lib/rubber/cloud/aws.rb
CHANGED
|
@@ -28,19 +28,21 @@ module Rubber
|
|
|
28
28
|
end
|
|
29
29
|
|
|
30
30
|
def create_image(image_name)
|
|
31
|
+
|
|
32
|
+
# validate all needed config set
|
|
33
|
+
["key_file", "pk_file", "cert_file", "account", "secret_access_key", "image_bucket"].each do |k|
|
|
34
|
+
raise "Set #{k} in rubber.yml" unless "#{env[k]}".strip.size > 0
|
|
35
|
+
end
|
|
36
|
+
raise "create_image can only be called from a capistrano scope" unless capistrano
|
|
37
|
+
|
|
31
38
|
ec2_key = env.key_file
|
|
32
39
|
ec2_pk = env.pk_file
|
|
33
40
|
ec2_cert = env.cert_file
|
|
41
|
+
|
|
34
42
|
ec2_key_dest = "/mnt/#{File.basename(ec2_key)}"
|
|
35
43
|
ec2_pk_dest = "/mnt/#{File.basename(ec2_pk)}"
|
|
36
44
|
ec2_cert_dest = "/mnt/#{File.basename(ec2_cert)}"
|
|
37
45
|
|
|
38
|
-
# validate all needed config set
|
|
39
|
-
["key_file", "pk_file", "cert_file", "account", "secret_access_key", "image_bucket"].each do |k|
|
|
40
|
-
raise "Set #{k} in rubber.yml" unless "#{env[k]}".strip.size > 0
|
|
41
|
-
end
|
|
42
|
-
raise "create_image can only be called from a capistrano scope" unless capistrano
|
|
43
|
-
|
|
44
46
|
storage(env.image_bucket).ensure_bucket
|
|
45
47
|
|
|
46
48
|
capistrano.put(File.read(ec2_key), ec2_key_dest)
|
|
@@ -51,7 +53,6 @@ module Rubber
|
|
|
51
53
|
arch = case arch when /i\d86/ then "i386" else arch end
|
|
52
54
|
|
|
53
55
|
capistrano.sudo_script "create_bundle", <<-CMD
|
|
54
|
-
rvm use system
|
|
55
56
|
export RUBYLIB=/usr/lib/site_ruby/
|
|
56
57
|
unset RUBYOPT
|
|
57
58
|
nohup ec2-bundle-vol --batch -d /mnt -k #{ec2_pk_dest} -c #{ec2_cert_dest} -u #{env.account} -p #{image_name} -r #{arch} &> /tmp/ec2-bundle-vol.log &
|
|
@@ -66,7 +67,6 @@ module Rubber
|
|
|
66
67
|
CMD
|
|
67
68
|
|
|
68
69
|
capistrano.sudo_script "register_bundle", <<-CMD
|
|
69
|
-
rvm use system
|
|
70
70
|
export RUBYLIB=/usr/lib/site_ruby/
|
|
71
71
|
unset RUBYOPT
|
|
72
72
|
echo "Uploading image to S3..."
|
data/lib/rubber/commands/cron.rb
CHANGED
data/lib/rubber/commands/util.rb
CHANGED
|
@@ -310,6 +310,52 @@ module Rubber
|
|
|
310
310
|
end
|
|
311
311
|
|
|
312
312
|
end
|
|
313
|
+
|
|
314
|
+
class Obfuscation < Clamp::Command
|
|
315
|
+
|
|
316
|
+
def self.subcommand_name
|
|
317
|
+
"util:obfuscation"
|
|
318
|
+
end
|
|
319
|
+
|
|
320
|
+
def self.subcommand_description
|
|
321
|
+
"Obfuscates rubber-secret.yml using encryption"
|
|
322
|
+
end
|
|
323
|
+
|
|
324
|
+
option ["-f", "--secretfile"],
|
|
325
|
+
"SECRETFILE",
|
|
326
|
+
"The rubber_secret file\n (default: <Rubber.config.rubber_secret>)"
|
|
327
|
+
|
|
328
|
+
option ["-k", "--secretkey"],
|
|
329
|
+
"SECRETKEY",
|
|
330
|
+
"The rubber_secret_key\n (default: <Rubber.config.rubber_secret_key>)"
|
|
313
331
|
|
|
332
|
+
option ["-d", "--decrypt"],
|
|
333
|
+
:flag,
|
|
334
|
+
"Decrypt and display the current rubber_secret"
|
|
335
|
+
|
|
336
|
+
option ["-g", "--generate"],
|
|
337
|
+
:flag,
|
|
338
|
+
"Generate a key for rubber_secret_key"
|
|
339
|
+
|
|
340
|
+
def execute
|
|
341
|
+
if generate?
|
|
342
|
+
puts "Obfuscation key: " + Rubber::Encryption.generate_encrypt_key.inspect
|
|
343
|
+
exit
|
|
344
|
+
else
|
|
345
|
+
signal_usage_error "Need to define a rubber_secret in rubber.yml" unless secretfile
|
|
346
|
+
signal_usage_error "Need to define a rubber_secret_key in rubber.yml" unless secretkey
|
|
347
|
+
signal_usage_error "The file pointed to by rubber_secret needs to exist" unless File.exist?(secretfile)
|
|
348
|
+
data = IO.read(secretfile)
|
|
349
|
+
|
|
350
|
+
if decrypt?
|
|
351
|
+
puts Rubber::Encryption.decrypt(data, secretkey)
|
|
352
|
+
else
|
|
353
|
+
puts Rubber::Encryption.encrypt(data, secretkey)
|
|
354
|
+
end
|
|
355
|
+
end
|
|
356
|
+
end
|
|
357
|
+
|
|
358
|
+
end
|
|
359
|
+
|
|
314
360
|
end
|
|
315
361
|
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
require 'openssl'
|
|
2
|
+
require 'base64'
|
|
3
|
+
|
|
4
|
+
module Rubber
|
|
5
|
+
module Encryption
|
|
6
|
+
|
|
7
|
+
def cipher_algorithm
|
|
8
|
+
OpenSSL::Cipher.new("AES-256-CBC")
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def cipher_digest
|
|
12
|
+
OpenSSL::Digest.new("SHA256")
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def generate_encrypt_key
|
|
16
|
+
OpenSSL::Digest.hexdigest('md5', rand.to_s)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def encrypt(payload, secret)
|
|
20
|
+
cipher = cipher_algorithm
|
|
21
|
+
|
|
22
|
+
cipher.encrypt
|
|
23
|
+
cipher.pkcs5_keyivgen(cipher_digest.hexdigest(secret))
|
|
24
|
+
|
|
25
|
+
encrypted_data = cipher.update(payload) + cipher.final
|
|
26
|
+
encoded_encrypted_data = Base64.encode64(encrypted_data)
|
|
27
|
+
|
|
28
|
+
return encoded_encrypted_data
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def decrypt(encoded_encrypted_data, secret)
|
|
32
|
+
cipher = cipher_algorithm
|
|
33
|
+
|
|
34
|
+
cipher.decrypt
|
|
35
|
+
cipher.pkcs5_keyivgen(cipher_digest.hexdigest(secret))
|
|
36
|
+
|
|
37
|
+
encrypted_data = Base64.decode64(encoded_encrypted_data)
|
|
38
|
+
payload = cipher.update(encrypted_data) + cipher.final
|
|
39
|
+
|
|
40
|
+
return payload
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
extend self
|
|
44
|
+
|
|
45
|
+
end
|
|
46
|
+
end
|
data/lib/rubber/environment.rb
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
require 'yaml'
|
|
2
2
|
require 'socket'
|
|
3
3
|
require 'delegate'
|
|
4
|
+
require 'rubber/encryption'
|
|
5
|
+
|
|
4
6
|
|
|
5
7
|
module Rubber
|
|
6
8
|
module Configuration
|
|
@@ -28,15 +30,17 @@ module Rubber
|
|
|
28
30
|
|
|
29
31
|
@items = {}
|
|
30
32
|
@config_files.each { |file| read_config(file) }
|
|
31
|
-
|
|
32
|
-
|
|
33
|
+
|
|
34
|
+
read_secret_config
|
|
33
35
|
end
|
|
34
36
|
|
|
35
37
|
def read_config(file)
|
|
36
38
|
Rubber.logger.debug{"Reading rubber configuration from #{file}"}
|
|
37
39
|
if File.exist?(file)
|
|
38
40
|
begin
|
|
39
|
-
|
|
41
|
+
data = IO.read(file)
|
|
42
|
+
data = yield(data) if block_given?
|
|
43
|
+
@items = Environment.combine(@items, YAML::load(ERB.new(data).result) || {})
|
|
40
44
|
rescue Exception => e
|
|
41
45
|
Rubber.logger.error{"Unable to read rubber configuration from #{file}"}
|
|
42
46
|
raise
|
|
@@ -44,6 +48,21 @@ module Rubber
|
|
|
44
48
|
end
|
|
45
49
|
end
|
|
46
50
|
|
|
51
|
+
def read_secret_config
|
|
52
|
+
bound = bind()
|
|
53
|
+
@config_secret = bound.rubber_secret
|
|
54
|
+
if @config_secret
|
|
55
|
+
obfuscation_key = bound.rubber_secret_key
|
|
56
|
+
if obfuscation_key
|
|
57
|
+
read_config(@config_secret) do |data|
|
|
58
|
+
Rubber::Encryption.decrypt(data, obfuscation_key)
|
|
59
|
+
end
|
|
60
|
+
else
|
|
61
|
+
read_config(@config_secret)
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
47
66
|
def known_roles
|
|
48
67
|
return @known_roles if @known_roles
|
|
49
68
|
|
|
@@ -89,7 +108,7 @@ module Rubber
|
|
|
89
108
|
if old.is_a?(Hash) && new.is_a?(Hash)
|
|
90
109
|
value = old.clone
|
|
91
110
|
new.each do |nk, nv|
|
|
92
|
-
if nk[0] == '^'
|
|
111
|
+
if nk.to_s[0..0] == '^'
|
|
93
112
|
nk = nk[1..-1]
|
|
94
113
|
value[nk] = combine(nil, nv)
|
|
95
114
|
else
|
|
@@ -212,4 +231,4 @@ module Rubber
|
|
|
212
231
|
end
|
|
213
232
|
|
|
214
233
|
end
|
|
215
|
-
end
|
|
234
|
+
end
|
|
@@ -63,7 +63,7 @@ namespace :rubber do
|
|
|
63
63
|
# NOTE: for some reason Capistrano requires you to have both the public and
|
|
64
64
|
# the private key in the same folder, the public key should have the
|
|
65
65
|
# extension ".pub".
|
|
66
|
-
ssh_options[:keys] = cloud.env.key_file
|
|
66
|
+
ssh_options[:keys] = [cloud.env.key_file].flatten
|
|
67
67
|
ssh_options[:timeout] = fetch(:ssh_timeout, 5)
|
|
68
68
|
end
|
|
69
69
|
|
|
@@ -79,18 +79,22 @@ namespace :rubber do
|
|
|
79
79
|
Stop the EC2 instance for the give ALIAS
|
|
80
80
|
DESC
|
|
81
81
|
required_task :stop do
|
|
82
|
-
|
|
82
|
+
instance_aliases = get_env('ALIAS', "Instance alias (e.g. web01 or web01~web05,web09)", true)
|
|
83
|
+
|
|
84
|
+
aliases = Rubber::Util::parse_aliases(instance_aliases)
|
|
83
85
|
ENV.delete('ROLES') # so we don't get an error if people leave ROLES in env from :create CLI
|
|
84
|
-
|
|
86
|
+
stop_instances(aliases)
|
|
85
87
|
end
|
|
86
88
|
|
|
87
89
|
desc <<-DESC
|
|
88
90
|
Start the EC2 instance for the give ALIAS
|
|
89
91
|
DESC
|
|
90
92
|
required_task :start do
|
|
91
|
-
|
|
93
|
+
instance_aliases = get_env('ALIAS', "Instance alias (e.g. web01 or web01~web05,web09)", true)
|
|
94
|
+
|
|
95
|
+
aliases = Rubber::Util::parse_aliases(instance_aliases)
|
|
92
96
|
ENV.delete('ROLES') # so we don't get an error if people leave ROLES in env from :create CLI
|
|
93
|
-
|
|
97
|
+
start_instances(aliases)
|
|
94
98
|
end
|
|
95
99
|
|
|
96
100
|
desc <<-DESC
|
|
@@ -465,50 +469,106 @@ namespace :rubber do
|
|
|
465
469
|
|
|
466
470
|
cloud.reboot_instance(instance_item.instance_id)
|
|
467
471
|
end
|
|
468
|
-
|
|
469
|
-
# Stops the given ec2
|
|
472
|
+
|
|
473
|
+
# Stops the given ec2 instances. Note that this operation only works for instances that use an EBS volume for the root
|
|
470
474
|
# device and that are not spot instances.
|
|
471
|
-
def
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
475
|
+
def stop_instances(aliases)
|
|
476
|
+
stop_threads = []
|
|
477
|
+
|
|
478
|
+
instance_items = aliases.collect{|instance_alias| rubber_instances[instance_alias]}
|
|
479
|
+
instance_items = aliases.collect do |instance_alias|
|
|
480
|
+
instance_item = rubber_instances[instance_alias]
|
|
481
|
+
|
|
482
|
+
fatal "Instance does not exist: #{instance_alias}" if ! instance_item
|
|
483
|
+
fatal "Cannot stop spot instances!" if ! instance_item.spot_instance_request_id.nil?
|
|
484
|
+
fatal "Cannot stop instances with instance-store root device!" if (instance_item.root_device_type != 'ebs')
|
|
485
|
+
|
|
486
|
+
instance_item
|
|
487
|
+
end
|
|
488
|
+
|
|
489
|
+
# Get user confirmation
|
|
490
|
+
human_instance_list = instance_items.collect{|instance_item| "#{instance_item.name} (#{instance_item.instance_id})"}.join(', ')
|
|
491
|
+
value = Capistrano::CLI.ui.ask("About to STOP #{human_instance_list} in mode #{Rubber.env}. Are you SURE [yes/NO]?: ")
|
|
480
492
|
fatal("Exiting", 0) if value != "yes"
|
|
493
|
+
|
|
494
|
+
instance_items.each do |instance_item|
|
|
495
|
+
logger.info "Stopping instance alias=#{instance_item.name}, instance_id=#{instance_item.instance_id}"
|
|
496
|
+
|
|
497
|
+
stop_threads << Thread.new do
|
|
498
|
+
env = rubber_cfg.environment.bind(instance_item.role_names, instance_item.name)
|
|
481
499
|
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
500
|
+
cloud.stop_instance(instance_item.instance_id)
|
|
501
|
+
|
|
502
|
+
stopped = false
|
|
503
|
+
while !stopped
|
|
504
|
+
sleep 1
|
|
505
|
+
instance = cloud.describe_instances(instance_item.instance_id).first rescue {}
|
|
506
|
+
stopped = (instance[:state] == "stopped")
|
|
507
|
+
end
|
|
508
|
+
end
|
|
509
|
+
end
|
|
510
|
+
|
|
511
|
+
print "Waiting for #{instance_items.size == 1 ? 'instance' : 'instances'} to stop"
|
|
512
|
+
while true do
|
|
513
|
+
print "."
|
|
514
|
+
sleep 2
|
|
515
|
+
break unless stop_threads.any?(&:alive?)
|
|
516
|
+
end
|
|
517
|
+
print "\n"
|
|
518
|
+
|
|
519
|
+
stop_threads.each(&:join)
|
|
485
520
|
end
|
|
486
521
|
|
|
487
|
-
# Starts the given ec2
|
|
522
|
+
# Starts the given ec2 instances. Note that this operation only works for instances that use an EBS volume for the root
|
|
488
523
|
# device, that are not spot instances, and that are already stopped.
|
|
489
|
-
def
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
524
|
+
def start_instances(aliases)
|
|
525
|
+
start_threads = []
|
|
526
|
+
refresh_threads = []
|
|
527
|
+
|
|
528
|
+
instance_items = aliases.collect do |instance_alias|
|
|
529
|
+
instance_item = rubber_instances[instance_alias]
|
|
530
|
+
|
|
531
|
+
fatal "Instance does not exist: #{instance_alias}" if ! instance_item
|
|
532
|
+
fatal "Cannot start spot instances!" if ! instance_item.spot_instance_request_id.nil?
|
|
533
|
+
fatal "Cannot start instances with instance-store root device!" if (instance_item.root_device_type != 'ebs')
|
|
534
|
+
|
|
535
|
+
instance_item
|
|
536
|
+
end
|
|
537
|
+
|
|
538
|
+
# Get user confirmation
|
|
539
|
+
human_instance_list = instance_items.collect{|instance_item| "#{instance_item.name} (#{instance_item.instance_id})"}.join(', ')
|
|
540
|
+
value = Capistrano::CLI.ui.ask("About to START #{human_instance_list} in mode #{Rubber.env}. Are you SURE [yes/NO]?: ")
|
|
498
541
|
fatal("Exiting", 0) if value != "yes"
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
542
|
+
|
|
543
|
+
instance_items.each do |instance_item|
|
|
544
|
+
logger.info "Starting instance alias=#{instance_item.name}, instance_id=#{instance_item.instance_id}"
|
|
545
|
+
|
|
546
|
+
start_threads << Thread.new do
|
|
547
|
+
env = rubber_cfg.environment.bind(instance_item.role_names, instance_item.name)
|
|
548
|
+
|
|
549
|
+
cloud.start_instance(instance_item.instance_id)
|
|
550
|
+
|
|
551
|
+
# Re-starting an instance will almost certainly give it a new set of IPs and DNS entries, so refresh the values.
|
|
552
|
+
refresh_threads << Thread.new do
|
|
553
|
+
while ! refresh_instance(instance_item.name)
|
|
554
|
+
sleep 1
|
|
555
|
+
end
|
|
556
|
+
end
|
|
557
|
+
end
|
|
558
|
+
end
|
|
559
|
+
|
|
560
|
+
print "Waiting for #{instance_items.size == 1 ? 'instance' : 'instances'} to start"
|
|
506
561
|
while true do
|
|
507
562
|
print "."
|
|
508
563
|
sleep 2
|
|
509
|
-
|
|
510
|
-
break if refresh_instance(instance_alias)
|
|
564
|
+
break unless start_threads.any?(&:alive?)
|
|
511
565
|
end
|
|
566
|
+
|
|
567
|
+
start_threads.each(&:join)
|
|
568
|
+
refresh_threads.each(&:join)
|
|
569
|
+
|
|
570
|
+
# Static IPs, DNS, etc. need to be set up for the started instances
|
|
571
|
+
post_refresh
|
|
512
572
|
end
|
|
513
573
|
|
|
514
574
|
# delete from ~/.ssh/known_hosts all lines that begin with ec2- or instance_alias
|
|
@@ -515,12 +515,17 @@ namespace :rubber do
|
|
|
515
515
|
if reboot
|
|
516
516
|
|
|
517
517
|
logger.info "Rebooting ..."
|
|
518
|
-
|
|
518
|
+
begin
|
|
519
|
+
run("#{sudo} reboot", :hosts => reboot_hosts)
|
|
520
|
+
# since we rebooted, teardown the connections to force cap to reconnect
|
|
521
|
+
teardown_connections_to(sessions.keys)
|
|
522
|
+
rescue
|
|
523
|
+
# swallow exception since there is a chance
|
|
524
|
+
# net:ssh throws an Exception
|
|
525
|
+
end
|
|
526
|
+
|
|
519
527
|
sleep 30
|
|
520
528
|
|
|
521
|
-
# since we rebooted, teardown the connections to force cap to reconnect
|
|
522
|
-
teardown_connections_to(sessions.keys)
|
|
523
|
-
|
|
524
529
|
reboot_hosts.each do |host|
|
|
525
530
|
direct_connection(host) do
|
|
526
531
|
run "echo"
|
|
@@ -19,8 +19,9 @@ namespace :rubber do
|
|
|
19
19
|
rubber_instances.save
|
|
20
20
|
end
|
|
21
21
|
|
|
22
|
-
# then, associate it if we don't have a record (on instance) of association
|
|
23
|
-
|
|
22
|
+
# then, associate it if we don't have a record (on instance) of association or it
|
|
23
|
+
# doesn't match the instance's current external ip
|
|
24
|
+
if !ic.static_ip || ip != ic.external_ip
|
|
24
25
|
logger.info "Associating static ip #{ip} with #{ic.full_name}"
|
|
25
26
|
associate_static_ip(ip, ic.instance_id)
|
|
26
27
|
|
data/lib/rubber/version.rb
CHANGED
data/rubber.gemspec
CHANGED
|
@@ -29,8 +29,7 @@ Gem::Specification.new do |s|
|
|
|
29
29
|
s.require_paths = ["lib"]
|
|
30
30
|
|
|
31
31
|
s.add_dependency 'capistrano', '~> 2.12'
|
|
32
|
-
|
|
33
|
-
s.add_dependency 'net-ssh', '~> 2.4.0'
|
|
32
|
+
s.add_dependency 'net-ssh', '~> 2.6'
|
|
34
33
|
s.add_dependency 'thor'
|
|
35
34
|
s.add_dependency 'clamp'
|
|
36
35
|
s.add_dependency 'open4'
|