rubber 1.0.2
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/CHANGELOG +39 -0
- data/COPYING +339 -0
- data/README +6 -0
- data/TODO +11 -0
- data/VERSION +1 -0
- data/bin/vulcanize +41 -0
- data/generators/vulcanize/USAGE +6 -0
- data/generators/vulcanize/templates/apache/config/rubber/deploy-apache.rb +51 -0
- data/generators/vulcanize/templates/apache/config/rubber/role/apache/deflate.conf +10 -0
- data/generators/vulcanize/templates/apache/config/rubber/role/apache/expires.conf +9 -0
- data/generators/vulcanize/templates/apache/config/rubber/role/apache/headers.conf +6 -0
- data/generators/vulcanize/templates/apache/config/rubber/role/apache/monit-apache.conf +8 -0
- data/generators/vulcanize/templates/apache/config/rubber/role/apache/ports.conf +5 -0
- data/generators/vulcanize/templates/apache/config/rubber/role/apache/setenvif.conf +52 -0
- data/generators/vulcanize/templates/apache/config/rubber/role/web_tools/tools-apache-vhost.conf +62 -0
- data/generators/vulcanize/templates/apache/config/rubber/role/web_tools/tools-apache.auth +7 -0
- data/generators/vulcanize/templates/apache/config/rubber/role/web_tools/tools-index.html +30 -0
- data/generators/vulcanize/templates/apache/config/rubber/rubber-apache.yml +7 -0
- data/generators/vulcanize/templates/apache/templates.yml +1 -0
- data/generators/vulcanize/templates/base/Capfile +14 -0
- data/generators/vulcanize/templates/base/config/deploy.rb +55 -0
- data/generators/vulcanize/templates/base/config/rubber/common/crontab +16 -0
- data/generators/vulcanize/templates/base/config/rubber/common/profile.rc +9 -0
- data/generators/vulcanize/templates/base/config/rubber/deploy-setup.rb +104 -0
- data/generators/vulcanize/templates/base/config/rubber/rubber.yml +241 -0
- data/generators/vulcanize/templates/base/lib/tasks/rubber.rake +15 -0
- data/generators/vulcanize/templates/base/script/cron-rake +18 -0
- data/generators/vulcanize/templates/base/script/cron-runner +18 -0
- data/generators/vulcanize/templates/base/script/cron-sh +67 -0
- data/generators/vulcanize/templates/base/templates.yml +1 -0
- data/generators/vulcanize/templates/complete_mongrel_mysql/config/rubber/role/haproxy/haproxy-mongrel.conf +23 -0
- data/generators/vulcanize/templates/complete_mongrel_mysql/config/rubber/role/nginx/nginx-mongrel.conf +113 -0
- data/generators/vulcanize/templates/complete_mongrel_mysql/config/rubber/rubber-complete.yml +41 -0
- data/generators/vulcanize/templates/complete_mongrel_mysql/templates.yml +6 -0
- data/generators/vulcanize/templates/complete_passenger_mysql/config/rubber/role/haproxy/haproxy-passenger.conf +19 -0
- data/generators/vulcanize/templates/complete_passenger_mysql/config/rubber/rubber-complete.yml +40 -0
- data/generators/vulcanize/templates/complete_passenger_mysql/templates.yml +10 -0
- data/generators/vulcanize/templates/cruise/config/rubber/deploy-cruise.rb +72 -0
- data/generators/vulcanize/templates/cruise/config/rubber/role/cruise/cruise +40 -0
- data/generators/vulcanize/templates/cruise/config/rubber/role/cruise/my.cnf +165 -0
- data/generators/vulcanize/templates/cruise/config/rubber/role/cruise/production.rb +8 -0
- data/generators/vulcanize/templates/cruise/config/rubber/role/cruise/site_config.rb +76 -0
- data/generators/vulcanize/templates/cruise/config/rubber/role/web_tools/cruise-nginx.conf +11 -0
- data/generators/vulcanize/templates/cruise/config/rubber/rubber-cruise.yml +18 -0
- data/generators/vulcanize/templates/cruise/templates.yml +1 -0
- data/generators/vulcanize/templates/haproxy/config/rubber/deploy-haproxy.rb +45 -0
- data/generators/vulcanize/templates/haproxy/config/rubber/role/haproxy/haproxy-base.conf +26 -0
- data/generators/vulcanize/templates/haproxy/config/rubber/role/haproxy/haproxy-default.conf +8 -0
- data/generators/vulcanize/templates/haproxy/config/rubber/role/haproxy/monit-haproxy.conf +9 -0
- data/generators/vulcanize/templates/haproxy/config/rubber/role/haproxy/syslog-haproxy.conf +6 -0
- data/generators/vulcanize/templates/haproxy/config/rubber/role/haproxy/syslogd-default.conf +17 -0
- data/generators/vulcanize/templates/haproxy/config/rubber/role/web_tools/haproxy-nginx.conf +10 -0
- data/generators/vulcanize/templates/haproxy/config/rubber/rubber-haproxy.yml +7 -0
- data/generators/vulcanize/templates/haproxy/templates.yml +1 -0
- data/generators/vulcanize/templates/memcached/config/memcached.yml +28 -0
- data/generators/vulcanize/templates/memcached/config/rubber/common/memcached.yml +14 -0
- data/generators/vulcanize/templates/memcached/config/rubber/role/memcached/memcached.conf +52 -0
- data/generators/vulcanize/templates/memcached/config/rubber/role/memcached/memcached_munin_plugin +249 -0
- data/generators/vulcanize/templates/memcached/config/rubber/rubber-memcached.yml +7 -0
- data/generators/vulcanize/templates/memcached/templates.yml +1 -0
- data/generators/vulcanize/templates/minimal_mysql/templates.yml +7 -0
- data/generators/vulcanize/templates/minimal_nodb/templates.yml +6 -0
- data/generators/vulcanize/templates/mongrel/config/rubber/deploy-mongrel.rb +75 -0
- data/generators/vulcanize/templates/mongrel/config/rubber/role/mongrel/mongrel_cluster.yml +12 -0
- data/generators/vulcanize/templates/mongrel/config/rubber/role/mongrel/monit-mongrel.conf +20 -0
- data/generators/vulcanize/templates/mongrel/config/rubber/rubber-mongrel.yml +9 -0
- data/generators/vulcanize/templates/mongrel/templates.yml +1 -0
- data/generators/vulcanize/templates/monit/config/rubber/common/monit-default.conf +15 -0
- data/generators/vulcanize/templates/monit/config/rubber/common/monit.conf +251 -0
- data/generators/vulcanize/templates/monit/config/rubber/deploy-monit.rb +32 -0
- data/generators/vulcanize/templates/monit/config/rubber/role/web_tools/monit-admin-nginx.conf +10 -0
- data/generators/vulcanize/templates/monit/config/rubber/rubber-monit.yml +6 -0
- data/generators/vulcanize/templates/monit/templates.yml +1 -0
- data/generators/vulcanize/templates/munin/config/rubber/common/monit-munin.conf +8 -0
- data/generators/vulcanize/templates/munin/config/rubber/common/munin-node.conf +48 -0
- data/generators/vulcanize/templates/munin/config/rubber/deploy-munin.rb +46 -0
- data/generators/vulcanize/templates/munin/config/rubber/role/web_tools/munin-nginx.conf +8 -0
- data/generators/vulcanize/templates/munin/config/rubber/role/web_tools/munin-plugins.conf +31 -0
- data/generators/vulcanize/templates/munin/config/rubber/role/web_tools/munin.conf +80 -0
- data/generators/vulcanize/templates/munin/config/rubber/rubber-munin.yml +8 -0
- data/generators/vulcanize/templates/munin/script/munin/example_mysql_query.rb +57 -0
- data/generators/vulcanize/templates/munin/script/munin/example_simple.rb +24 -0
- data/generators/vulcanize/templates/munin/templates.yml +1 -0
- data/generators/vulcanize/templates/mysql/config/rubber/common/database.yml +11 -0
- data/generators/vulcanize/templates/mysql/config/rubber/deploy-mysql.rb +156 -0
- data/generators/vulcanize/templates/mysql/config/rubber/role/db/crontab +14 -0
- data/generators/vulcanize/templates/mysql/config/rubber/role/db/monit-mysql.cnf +10 -0
- data/generators/vulcanize/templates/mysql/config/rubber/role/db/my.cnf +167 -0
- data/generators/vulcanize/templates/mysql/config/rubber/role/mysql_slave/mysql_slave_munin_plugin +51 -0
- data/generators/vulcanize/templates/mysql/config/rubber/rubber-mysql.yml +46 -0
- data/generators/vulcanize/templates/mysql/templates.yml +1 -0
- data/generators/vulcanize/templates/mysql_cluster/config/rubber/common/mysql_cluster_migrations.rb +13 -0
- data/generators/vulcanize/templates/mysql_cluster/config/rubber/deploy-mysql_cluster.rb +173 -0
- data/generators/vulcanize/templates/mysql_cluster/config/rubber/role/mysql_data/my.cnf +15 -0
- data/generators/vulcanize/templates/mysql_cluster/config/rubber/role/mysql_mgm/ndb_mgmd.cnf +39 -0
- data/generators/vulcanize/templates/mysql_cluster/config/rubber/role/mysql_sql/monit-mysql_cluster_sql.cnf +10 -0
- data/generators/vulcanize/templates/mysql_cluster/config/rubber/role/mysql_sql/my.cnf +23 -0
- data/generators/vulcanize/templates/mysql_cluster/config/rubber/rubber-mysql_cluster.yml +32 -0
- data/generators/vulcanize/templates/mysql_cluster/templates.yml +1 -0
- data/generators/vulcanize/templates/mysql_proxy/config/rubber/common/database.yml +16 -0
- data/generators/vulcanize/templates/mysql_proxy/config/rubber/common/monit-mysql_proxy.cnf +10 -0
- data/generators/vulcanize/templates/mysql_proxy/config/rubber/common/mysql-proxy +153 -0
- data/generators/vulcanize/templates/mysql_proxy/config/rubber/common/mysql-proxy.conf +10 -0
- data/generators/vulcanize/templates/mysql_proxy/config/rubber/common/mysql-proxy.lua +5 -0
- data/generators/vulcanize/templates/mysql_proxy/config/rubber/deploy-mysql_proxy.rb +52 -0
- data/generators/vulcanize/templates/mysql_proxy/config/rubber/rubber-mysql_proxy.yml +11 -0
- data/generators/vulcanize/templates/mysql_proxy/templates.yml +1 -0
- data/generators/vulcanize/templates/nginx/config/rubber/deploy-nginx.rb +45 -0
- data/generators/vulcanize/templates/nginx/config/rubber/role/nginx/crontab +9 -0
- data/generators/vulcanize/templates/nginx/config/rubber/role/nginx/monit-nginx.conf +8 -0
- data/generators/vulcanize/templates/nginx/config/rubber/role/nginx/nginx.conf +42 -0
- data/generators/vulcanize/templates/nginx/config/rubber/role/web_tools/nginx-tools.conf +55 -0
- data/generators/vulcanize/templates/nginx/config/rubber/role/web_tools/tools-index.html +30 -0
- data/generators/vulcanize/templates/nginx/config/rubber/role/web_tools/tools-nginx.auth +7 -0
- data/generators/vulcanize/templates/nginx/config/rubber/rubber-nginx.yml +10 -0
- data/generators/vulcanize/templates/nginx/templates.yml +1 -0
- data/generators/vulcanize/templates/passenger/config/rubber/deploy-passenger.rb +37 -0
- data/generators/vulcanize/templates/passenger/config/rubber/role/passenger/munin-passenger-sudoers.conf +6 -0
- data/generators/vulcanize/templates/passenger/config/rubber/role/passenger/munin-passenger.conf +47 -0
- data/generators/vulcanize/templates/passenger/config/rubber/role/passenger/passenger-apache-vhost.conf +46 -0
- data/generators/vulcanize/templates/passenger/config/rubber/role/passenger/passenger.conf +10 -0
- data/generators/vulcanize/templates/passenger/config/rubber/rubber-passenger.yml +12 -0
- data/generators/vulcanize/templates/passenger/templates.yml +1 -0
- data/generators/vulcanize/templates/sphinx/config/rubber/common/sphinx.yml +46 -0
- data/generators/vulcanize/templates/sphinx/config/rubber/deploy-sphinx.rb +112 -0
- data/generators/vulcanize/templates/sphinx/config/rubber/role/sphinx/crontab +11 -0
- data/generators/vulcanize/templates/sphinx/config/rubber/role/sphinx/monit-sphinx.conf +10 -0
- data/generators/vulcanize/templates/sphinx/config/rubber/rubber-sphinx.yml +6 -0
- data/generators/vulcanize/templates/sphinx/templates.yml +1 -0
- data/generators/vulcanize/vulcanize_generator.rb +67 -0
- data/lib/capistrano/hostcmd.rb +12 -0
- data/lib/rubber.rb +38 -0
- data/lib/rubber/capistrano.rb +1 -0
- data/lib/rubber/cloud.rb +13 -0
- data/lib/rubber/cloud/aws.rb +305 -0
- data/lib/rubber/cloud/base.rb +16 -0
- data/lib/rubber/configuration.rb +47 -0
- data/lib/rubber/dns.rb +13 -0
- data/lib/rubber/dns/base.rb +69 -0
- data/lib/rubber/dns/dyndns.rb +63 -0
- data/lib/rubber/dns/nettica.rb +73 -0
- data/lib/rubber/dns/zerigo.rb +131 -0
- data/lib/rubber/environment.rb +161 -0
- data/lib/rubber/generator.rb +197 -0
- data/lib/rubber/instance.rb +165 -0
- data/lib/rubber/recipes/rubber.rb +89 -0
- data/lib/rubber/recipes/rubber/bundles.rb +28 -0
- data/lib/rubber/recipes/rubber/deploy.rb +90 -0
- data/lib/rubber/recipes/rubber/instances.rb +348 -0
- data/lib/rubber/recipes/rubber/load_balancers.rb +44 -0
- data/lib/rubber/recipes/rubber/security_groups.rb +189 -0
- data/lib/rubber/recipes/rubber/setup.rb +357 -0
- data/lib/rubber/recipes/rubber/static_ips.rb +107 -0
- data/lib/rubber/recipes/rubber/utils.rb +203 -0
- data/lib/rubber/recipes/rubber/volumes.rb +264 -0
- data/lib/rubber/tasks/rubber.rb +221 -0
- data/lib/rubber/util.rb +37 -0
- data/test/environment_test.rb +118 -0
- data/test/generator_test.rb +323 -0
- data/test/instance_test.rb +93 -0
- data/test/test_helper.rb +4 -0
- data/test/util_test.rb +16 -0
- metadata +274 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
namespace :rubber do
|
|
2
|
+
|
|
3
|
+
desc "Back up and register an image of the running instance"
|
|
4
|
+
task :bundle do
|
|
5
|
+
if find_servers_for_task(current_task).size > 1
|
|
6
|
+
fatal "Can only bundle a single instance at a time, use FILTER to limit the scope"
|
|
7
|
+
end
|
|
8
|
+
image_name = get_env('IMAGE', "The image name for the bundle", true, Time.now.strftime("%Y%m%d_%H%M"))
|
|
9
|
+
image_id = cloud.create_image(image_name)
|
|
10
|
+
logger.info "Newly registered image is: #{image_id}"
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
desc "De-register and Destroy the image for the given name"
|
|
14
|
+
required_task :destroy_bundle do
|
|
15
|
+
image_id = get_env('IMAGE_ID', 'The id of the image to be destroyed', true)
|
|
16
|
+
cloud.destroy_image(image_id)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
desc "Describes all your own image bundles"
|
|
20
|
+
required_task :describe_bundles do
|
|
21
|
+
images = cloud.describe_images()
|
|
22
|
+
images.each do |image|
|
|
23
|
+
logger.info "ID: #{image[:id]}"
|
|
24
|
+
logger.info "Location: #{image[:location]}"
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
end
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
namespace :rubber do
|
|
2
|
+
|
|
3
|
+
# Add in some hooks so that we can insert our own hooks at head/tail of
|
|
4
|
+
# hook chain - this is needed for making monit stop before everyone else.
|
|
5
|
+
before "deploy:start", "rubber:pre_start"
|
|
6
|
+
before "deploy:restart", "rubber:pre_restart"
|
|
7
|
+
before "deploy:stop", "rubber:pre_stop"
|
|
8
|
+
on :load do
|
|
9
|
+
after "deploy:start", "rubber:post_start"
|
|
10
|
+
after "deploy:restart", "rubber:post_restart"
|
|
11
|
+
after "deploy:stop", "rubber:post_stop"
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
task :pre_start do
|
|
15
|
+
end
|
|
16
|
+
task :pre_restart do
|
|
17
|
+
end
|
|
18
|
+
task :pre_stop do
|
|
19
|
+
end
|
|
20
|
+
task :post_start do
|
|
21
|
+
end
|
|
22
|
+
task :post_restart do
|
|
23
|
+
end
|
|
24
|
+
task :post_stop do
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Don't want to do rubber:config for update_code as that tree isn't official
|
|
28
|
+
# until it is 'committed' by the symlink task (and doing so causes it to run
|
|
29
|
+
# for bootstrap_db which should only config the db config file). However,
|
|
30
|
+
# deploy:migrations doesn't call update, so we need an additional trigger for
|
|
31
|
+
# it
|
|
32
|
+
after "deploy:update", "rubber:config"
|
|
33
|
+
after "deploy:rollback_code", "rubber:config"
|
|
34
|
+
before "deploy:migrate", "rubber:config"
|
|
35
|
+
|
|
36
|
+
desc <<-DESC
|
|
37
|
+
Configures the deployed rails application by running the rubber configuration process
|
|
38
|
+
DESC
|
|
39
|
+
task :config do
|
|
40
|
+
opts = {}
|
|
41
|
+
opts['NO_POST'] = true if ENV['NO_POST']
|
|
42
|
+
opts['FILE'] = ENV['FILE'] if ENV['FILE']
|
|
43
|
+
opts['RUBBER_ENV'] = RUBBER_ENV
|
|
44
|
+
# we need to set rails env as well because when running rake
|
|
45
|
+
# in a rails project, rails gets loaded before the rubber hook gets run
|
|
46
|
+
opts['RAILS_ENV'] = RUBBER_ENV
|
|
47
|
+
|
|
48
|
+
# when running deploy:migrations, we need to run config against release_path
|
|
49
|
+
opts[:deploy_path] = current_release if fetch(:migrate_target, :current).to_sym == :latest
|
|
50
|
+
|
|
51
|
+
run_config(opts)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# because we start server as appserver user, but migrate as root, server needs to be able to write logs, etc.
|
|
55
|
+
before "rubber:pre_start", "rubber:setup_app_permissions"
|
|
56
|
+
before "rubber:pre_restart", "rubber:setup_app_permissions"
|
|
57
|
+
|
|
58
|
+
desc <<-DESC
|
|
59
|
+
Sets permissions of files in application directory to be owned by app_user.
|
|
60
|
+
DESC
|
|
61
|
+
task :setup_app_permissions do
|
|
62
|
+
run "find #{shared_path} -name cached-copy -prune -o -print | xargs chown #{rubber_env.app_user}:#{rubber_env.app_user}"
|
|
63
|
+
run "chown -R #{rubber_env.app_user}:#{rubber_env.app_user} #{current_path}/tmp"
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def run_config(options={})
|
|
67
|
+
path = options.delete(:deploy_path) || current_path
|
|
68
|
+
extra_env = options.keys.inject("") {|all, k| "#{all} #{k}=\"#{options[k]}\""}
|
|
69
|
+
|
|
70
|
+
# Need to do this so we can work with staging instances without having to
|
|
71
|
+
# checkin instance file between create and bootstrap, as well as during a deploy
|
|
72
|
+
if fetch(:push_instance_config, false)
|
|
73
|
+
push_files = [rubber_instances.file] + rubber_cfg.environment.config_files
|
|
74
|
+
push_files.each do |file|
|
|
75
|
+
dest_file = file.sub(/^#{RUBBER_ROOT}\/?/, '')
|
|
76
|
+
put(File.read(file), File.join(path, dest_file), :mode => "+r")
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# if the user has defined a secret config file, then push it into RUBBER_ROOT/config/rubber
|
|
81
|
+
secret = rubber_cfg.environment.config_secret
|
|
82
|
+
if secret && File.exist?(secret)
|
|
83
|
+
base = rubber_cfg.environment.config_root.sub(/^#{RUBBER_ROOT}\/?/, '')
|
|
84
|
+
put(File.read(secret), File.join(path, base, File.basename(secret)), :mode => "+r")
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
sudo "sh -c 'cd #{path} && #{extra_env} rake rubber:config'"
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
end
|
|
@@ -0,0 +1,348 @@
|
|
|
1
|
+
namespace :rubber do
|
|
2
|
+
|
|
3
|
+
desc <<-DESC
|
|
4
|
+
Create a new EC2 instance with the given ALIAS and ROLES
|
|
5
|
+
DESC
|
|
6
|
+
required_task :create do
|
|
7
|
+
instance_alias = get_env('ALIAS', "Instance alias (e.g. web01)", true)
|
|
8
|
+
r = get_env('ROLES', "Instance roles (e.g. web,app,db:primary=true)", true)
|
|
9
|
+
if r == '*'
|
|
10
|
+
instance_roles = rubber_cfg.environment.known_roles
|
|
11
|
+
instance_roles = instance_roles.collect {|role| role == "db" ? "db:primary=true" : role }
|
|
12
|
+
else
|
|
13
|
+
instance_roles = r.split(",")
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
ir = []
|
|
17
|
+
instance_roles.each do |r|
|
|
18
|
+
role = Rubber::Configuration::RoleItem.parse(r)
|
|
19
|
+
|
|
20
|
+
# If user doesn't setup a primary db, then be nice and do it
|
|
21
|
+
if role.name == "db" && role.options["primary"] == nil && rubber_instances.for_role("db").size == 0
|
|
22
|
+
value = Capistrano::CLI.ui.ask("You do not have a primary db role, should #{instance_alias} be it [y/n]?: ")
|
|
23
|
+
role.options["primary"] = true if value =~ /^y/
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
ir << role
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Add in roles that the given set of roles depends on
|
|
30
|
+
ir = Rubber::Configuration::RoleItem.expand_role_dependencies(ir, get_role_dependencies)
|
|
31
|
+
|
|
32
|
+
create_instance(instance_alias, ir)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
desc <<-DESC
|
|
36
|
+
Refresh the host data for a EC2 instance with the given ALIAS.
|
|
37
|
+
This is useful to run when rubber:create fails after instance creation
|
|
38
|
+
DESC
|
|
39
|
+
task :refresh do
|
|
40
|
+
instance_alias = get_env('ALIAS', "Instance alias (e.g. web01)", true)
|
|
41
|
+
ENV.delete('ROLES') # so we don't get an error if people leave ROLES in env from :create CLI
|
|
42
|
+
refresh_instance(instance_alias)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
desc <<-DESC
|
|
46
|
+
Destroy the EC2 instance for the given ALIAS
|
|
47
|
+
DESC
|
|
48
|
+
task :destroy do
|
|
49
|
+
instance_alias = get_env('ALIAS', "Instance alias (e.g. web01)", true)
|
|
50
|
+
ENV.delete('ROLES') # so we don't get an error if people leave ROLES in env from :create CLI
|
|
51
|
+
destroy_instance(instance_alias)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
desc <<-DESC
|
|
55
|
+
Destroy ALL the EC2 instances for the current env
|
|
56
|
+
DESC
|
|
57
|
+
task :destroy_all do
|
|
58
|
+
rubber_instances.each do |ic|
|
|
59
|
+
destroy_instance(ic.name)
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
desc <<-DESC
|
|
64
|
+
Adds the given ROLES to the instance named ALIAS
|
|
65
|
+
DESC
|
|
66
|
+
required_task :add_role do
|
|
67
|
+
instance_alias = get_env('ALIAS', "Instance alias (e.g. web01)", true)
|
|
68
|
+
r = get_env('ROLES', "Instance roles (e.g. web,app,db:primary=true)", true)
|
|
69
|
+
|
|
70
|
+
instance_roles = r.split(",")
|
|
71
|
+
|
|
72
|
+
ir = []
|
|
73
|
+
instance_roles.each do |r|
|
|
74
|
+
role = Rubber::Configuration::RoleItem.parse(r)
|
|
75
|
+
ir << role
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# Add in roles that the given set of roles depends on
|
|
79
|
+
ir = Rubber::Configuration::RoleItem.expand_role_dependencies(ir, get_role_dependencies)
|
|
80
|
+
|
|
81
|
+
instance = rubber_instances[instance_alias]
|
|
82
|
+
fatal "Instance does not exist: #{instance_alias}" unless instance
|
|
83
|
+
|
|
84
|
+
instance.roles = (instance.roles + ir).uniq
|
|
85
|
+
rubber_instances.save()
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
desc <<-DESC
|
|
89
|
+
Removes the given ROLES from the instance named ALIAS
|
|
90
|
+
DESC
|
|
91
|
+
required_task :remove_role do
|
|
92
|
+
instance_alias = get_env('ALIAS', "Instance alias (e.g. web01)", true)
|
|
93
|
+
r = get_env('ROLES', "Instance roles (e.g. web,app,db:primary=true)", true)
|
|
94
|
+
|
|
95
|
+
instance_roles = r.split(",")
|
|
96
|
+
|
|
97
|
+
ir = []
|
|
98
|
+
instance_roles.each do |r|
|
|
99
|
+
role = Rubber::Configuration::RoleItem.parse(r)
|
|
100
|
+
ir << role
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
instance = rubber_instances[instance_alias]
|
|
104
|
+
fatal "Instance does not exist: #{instance_alias}" unless instance
|
|
105
|
+
|
|
106
|
+
instance.roles = (instance.roles - ir).uniq
|
|
107
|
+
rubber_instances.save()
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
desc <<-DESC
|
|
111
|
+
List all your EC2 instances
|
|
112
|
+
DESC
|
|
113
|
+
required_task :describe do
|
|
114
|
+
results = []
|
|
115
|
+
format = "%-10s %-10s %-10s %-15s %-30s"
|
|
116
|
+
results << format % %w[InstanceID State Zone IP Alias\ (*=unknown)]
|
|
117
|
+
|
|
118
|
+
instances = cloud.describe_instances()
|
|
119
|
+
instances.each do |instance|
|
|
120
|
+
local_alias = find_alias(instance[:external_ip], instance[:id], instance[:state] == 'running')
|
|
121
|
+
results << format % [instance[:id], instance[:state], instance[:zone], instance[:external_ip] || "NoIP", local_alias || "Unknown"]
|
|
122
|
+
end
|
|
123
|
+
results.each {|r| logger.info r}
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
desc <<-DESC
|
|
127
|
+
Describes the availability zones
|
|
128
|
+
DESC
|
|
129
|
+
required_task :describe_zones do
|
|
130
|
+
results = []
|
|
131
|
+
format = "%-20s %-15s"
|
|
132
|
+
results << format % %w[Name State]
|
|
133
|
+
|
|
134
|
+
zones = cloud.describe_availability_zones()
|
|
135
|
+
zones.each do |zone|
|
|
136
|
+
results << format % [zone[:name], zone[:state]]
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
results.each {|r| logger.info r}
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
set :print_ip_command, "ifconfig eth0 | awk 'NR==2 {print $2}' | awk -F: '{print $2}'"
|
|
144
|
+
|
|
145
|
+
# Creates a new ec2 instance with the given alias and roles
|
|
146
|
+
# Configures aliases (/etc/hosts) on local and remote machines
|
|
147
|
+
def create_instance(instance_alias, instance_roles)
|
|
148
|
+
fatal "Instance already exists: #{instance_alias}" if rubber_instances[instance_alias]
|
|
149
|
+
|
|
150
|
+
role_names = instance_roles.collect{|x| x.name}
|
|
151
|
+
env = rubber_cfg.environment.bind(role_names, instance_alias)
|
|
152
|
+
|
|
153
|
+
# We need to use security_groups during create, so create them up front
|
|
154
|
+
setup_security_groups(instance_alias, role_names)
|
|
155
|
+
security_groups = get_assigned_security_groups(instance_alias, role_names)
|
|
156
|
+
|
|
157
|
+
ami = env.cloud_providers[env.cloud_provider].image_id
|
|
158
|
+
ami_type = env.cloud_providers[env.cloud_provider].image_type
|
|
159
|
+
availability_zone = env.availability_zone
|
|
160
|
+
logger.info "Creating instance #{ami}/#{ami_type}/#{security_groups.join(',') rescue 'Default'}/#{availability_zone || 'Default'}"
|
|
161
|
+
instance_id = cloud.create_instance(ami, ami_type, security_groups, availability_zone)
|
|
162
|
+
|
|
163
|
+
logger.info "Instance #{instance_id} created"
|
|
164
|
+
|
|
165
|
+
instance_item = Rubber::Configuration::InstanceItem.new(instance_alias, env.domain, instance_roles, instance_id, security_groups)
|
|
166
|
+
rubber_instances.add(instance_item)
|
|
167
|
+
rubber_instances.save()
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
print "Waiting for instance to start"
|
|
171
|
+
while true do
|
|
172
|
+
print "."
|
|
173
|
+
sleep 2
|
|
174
|
+
instance = cloud.describe_instances(instance_id).first
|
|
175
|
+
|
|
176
|
+
if instance[:state] == "running"
|
|
177
|
+
print "\n"
|
|
178
|
+
logger.info "Instance running, fetching hostname/ip data"
|
|
179
|
+
instance_item.external_host = instance[:external_host]
|
|
180
|
+
instance_item.external_ip = instance[:external_ip]
|
|
181
|
+
instance_item.internal_host = instance[:internal_host]
|
|
182
|
+
instance_item.zone = instance[:zone]
|
|
183
|
+
rubber_instances.save()
|
|
184
|
+
|
|
185
|
+
# setup amazon elastic ips if configured to do so
|
|
186
|
+
setup_static_ips
|
|
187
|
+
|
|
188
|
+
# Need to setup aliases so ssh doesn't give us errors when we
|
|
189
|
+
# later try? to connect to same ip but using alias
|
|
190
|
+
setup_local_aliases
|
|
191
|
+
|
|
192
|
+
# re-load the roles since we may have just defined new ones
|
|
193
|
+
load_roles() unless env.disable_auto_roles
|
|
194
|
+
|
|
195
|
+
# Connect to newly created instance and grab its internal ip
|
|
196
|
+
# so that we can update all aliases
|
|
197
|
+
|
|
198
|
+
task :_get_ip, :hosts => instance_item.external_ip do
|
|
199
|
+
instance_item.internal_ip = capture(print_ip_command).strip
|
|
200
|
+
rubber_instances.save()
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
# even though instance is running, sometimes ssh hasn't started yet,
|
|
204
|
+
# so retry on connect failure
|
|
205
|
+
begin
|
|
206
|
+
_get_ip
|
|
207
|
+
rescue ConnectionError
|
|
208
|
+
sleep 2
|
|
209
|
+
logger.info "Failed to connect to #{instance_alias} (#{instance_item.external_ip}), retrying"
|
|
210
|
+
retry
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
# Add the aliases for this instance to all other hosts
|
|
214
|
+
setup_remote_aliases
|
|
215
|
+
setup_dns_aliases
|
|
216
|
+
|
|
217
|
+
break
|
|
218
|
+
end
|
|
219
|
+
end
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
# Refreshes a ec2 instance with the given alias
|
|
223
|
+
# Configures aliases (/etc/hosts) on local and remote machines
|
|
224
|
+
def refresh_instance(instance_alias)
|
|
225
|
+
instance_item = rubber_instances[instance_alias]
|
|
226
|
+
|
|
227
|
+
fatal "Instance does not exist: #{instance_alias}" if ! instance_item
|
|
228
|
+
|
|
229
|
+
env = rubber_cfg.environment.bind(instance_item.role_names, instance_alias)
|
|
230
|
+
|
|
231
|
+
instance = cloud.describe_instances(instance_item.instance_id).first
|
|
232
|
+
|
|
233
|
+
if instance[:state] == "running"
|
|
234
|
+
logger.info "\nInstance running, fetching hostname/ip data"
|
|
235
|
+
instance_item.external_host = instance[:external_host]
|
|
236
|
+
instance_item.external_ip = instance[:external_ip]
|
|
237
|
+
instance_item.internal_host = instance[:internal_host]
|
|
238
|
+
instance_item.zone = instance[:zone]
|
|
239
|
+
|
|
240
|
+
# setup amazon elastic ips if configured to do so
|
|
241
|
+
setup_static_ips
|
|
242
|
+
|
|
243
|
+
# Need to setup aliases so ssh doesn't give us errors when we
|
|
244
|
+
# later try to connect to same ip but using alias
|
|
245
|
+
setup_local_aliases
|
|
246
|
+
|
|
247
|
+
# re-load the roles since we may have just defined new ones
|
|
248
|
+
load_roles() unless env.disable_auto_roles
|
|
249
|
+
|
|
250
|
+
# Connect to newly created instance and grab its internal ip
|
|
251
|
+
# so that we can update all aliases
|
|
252
|
+
task :_get_ip, :hosts => instance_item.external_ip do
|
|
253
|
+
instance_item.internal_ip = capture(print_ip_command).strip
|
|
254
|
+
rubber_instances.save()
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
# even though instance is running, sometimes ssh hasn't started yet,
|
|
258
|
+
# so retry on connect failure
|
|
259
|
+
begin
|
|
260
|
+
_get_ip
|
|
261
|
+
rescue ConnectionError
|
|
262
|
+
sleep 2
|
|
263
|
+
logger.info "Failed to connect to #{instance_alias} (#{instance_item.external_ip}), retrying"
|
|
264
|
+
retry
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
# Add the aliases for this instance to all other hosts
|
|
269
|
+
setup_remote_aliases
|
|
270
|
+
setup_dns_aliases
|
|
271
|
+
end
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
|
|
275
|
+
# Destroys the given ec2 instance
|
|
276
|
+
def destroy_instance(instance_alias)
|
|
277
|
+
instance_item = rubber_instances[instance_alias]
|
|
278
|
+
fatal "Instance does not exist: #{instance_alias}" if ! instance_item
|
|
279
|
+
|
|
280
|
+
env = rubber_cfg.environment.bind(instance_item.role_names, instance_item.name)
|
|
281
|
+
|
|
282
|
+
value = Capistrano::CLI.ui.ask("About to DESTROY #{instance_alias} (#{instance_item.instance_id}) in mode #{RUBBER_ENV}. Are you SURE [yes/NO]?: ")
|
|
283
|
+
fatal("Exiting", 0) if value != "yes"
|
|
284
|
+
|
|
285
|
+
if instance_item.static_ip
|
|
286
|
+
value = Capistrano::CLI.ui.ask("Instance has a static ip, do you want to release it? [y/N]?: ")
|
|
287
|
+
destroy_static_ip(instance_item.static_ip) if value =~ /^y/
|
|
288
|
+
end
|
|
289
|
+
|
|
290
|
+
if instance_item.volumes
|
|
291
|
+
value = Capistrano::CLI.ui.ask("Instance has persistent volumes, do you want to destroy them? [y/N]?: ")
|
|
292
|
+
if value =~ /^y/
|
|
293
|
+
instance_item.volumes.clone.each do |volume_id|
|
|
294
|
+
destroy_volume(volume_id)
|
|
295
|
+
end
|
|
296
|
+
end
|
|
297
|
+
end
|
|
298
|
+
|
|
299
|
+
logger.info "Destroying instance alias=#{instance_alias}, instance_id=#{instance_item.instance_id}"
|
|
300
|
+
|
|
301
|
+
cloud.destroy_instance(instance_item.instance_id)
|
|
302
|
+
|
|
303
|
+
rubber_instances.remove(instance_alias)
|
|
304
|
+
rubber_instances.save()
|
|
305
|
+
|
|
306
|
+
# re-load the roles since we just removed some and setup_remote_aliases
|
|
307
|
+
# shouldn't hit removed ones
|
|
308
|
+
load_roles() unless env.disable_auto_roles
|
|
309
|
+
|
|
310
|
+
setup_aliases
|
|
311
|
+
destroy_dyndns(instance_item)
|
|
312
|
+
cleanup_known_hosts(instance_item) unless env.disable_known_hosts_cleanup
|
|
313
|
+
end
|
|
314
|
+
|
|
315
|
+
|
|
316
|
+
# delete from ~/.ssh/known_hosts all lines that begin with ec2- or instance_alias
|
|
317
|
+
def cleanup_known_hosts(instance_item)
|
|
318
|
+
logger.info "Cleaning ~/.ssh/known_hosts"
|
|
319
|
+
File.open(File.expand_path('~/.ssh/known_hosts'), 'r+') do |f|
|
|
320
|
+
out = ""
|
|
321
|
+
f.each do |line|
|
|
322
|
+
line = case line
|
|
323
|
+
when /^ec2-/; ''
|
|
324
|
+
when /#{instance_item.full_name}/; ''
|
|
325
|
+
when /#{instance_item.external_host}/; ''
|
|
326
|
+
when /#{instance_item.external_ip}/; ''
|
|
327
|
+
else line;
|
|
328
|
+
end
|
|
329
|
+
out << line
|
|
330
|
+
end
|
|
331
|
+
f.pos = 0
|
|
332
|
+
f.print out
|
|
333
|
+
f.truncate(f.pos)
|
|
334
|
+
end
|
|
335
|
+
end
|
|
336
|
+
|
|
337
|
+
def get_role_dependencies
|
|
338
|
+
# convert string format of role_dependencies from rubber.yml into
|
|
339
|
+
# objects for use by expand_role_dependencies
|
|
340
|
+
deps = {}
|
|
341
|
+
rubber_env.role_dependencies.each do |k, v|
|
|
342
|
+
rhs = Array(v).collect {|r| Rubber::Configuration::RoleItem.parse(r)}
|
|
343
|
+
deps[Rubber::Configuration::RoleItem.parse(k)] = rhs
|
|
344
|
+
end if rubber_env.role_dependencies
|
|
345
|
+
return deps
|
|
346
|
+
end
|
|
347
|
+
|
|
348
|
+
end
|