mdh-ec2onrails 0.9.10
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 +180 -0
- data/COPYING +339 -0
- data/Manifest +162 -0
- data/README.textile +214 -0
- data/Rakefile +36 -0
- data/TODO +102 -0
- data/ec2onrails.gemspec +42 -0
- data/examples/Capfile +3 -0
- data/examples/deploy.rb +101 -0
- data/examples/s3.yml +9 -0
- data/lib/ec2onrails.rb +20 -0
- data/lib/ec2onrails/capistrano_utils.rb +43 -0
- data/lib/ec2onrails/recipes.rb +844 -0
- data/lib/ec2onrails/version.rb +31 -0
- data/server/build-ec2onrails.sh +44 -0
- data/server/files/etc/aliases +5 -0
- data/server/files/etc/aliases.db +0 -0
- data/server/files/etc/apache2/apache2.conf +295 -0
- data/server/files/etc/apache2/conf.d/app.proxy_cluster.conf +7 -0
- data/server/files/etc/apache2/conf.d/app.proxy_frontend.conf +10 -0
- data/server/files/etc/apache2/mods-available/proxy.conf +18 -0
- data/server/files/etc/apache2/sites-available/app.common +56 -0
- data/server/files/etc/apache2/sites-available/app.custom +0 -0
- data/server/files/etc/apache2/sites-available/default +14 -0
- data/server/files/etc/apache2/sites-available/default-ssl +19 -0
- data/server/files/etc/cron.d/backup_app_db_to_s3 +16 -0
- data/server/files/etc/cron.daily/app +9 -0
- data/server/files/etc/cron.daily/logrotate_post +19 -0
- data/server/files/etc/cron.hourly/app +10 -0
- data/server/files/etc/cron.monthly/app +10 -0
- data/server/files/etc/cron.weekly/app +10 -0
- data/server/files/etc/denyhosts.conf +628 -0
- data/server/files/etc/dpkg/dpkg.cfg +13 -0
- data/server/files/etc/ec2onrails/README +32 -0
- data/server/files/etc/ec2onrails/balancer_members +6 -0
- data/server/files/etc/ec2onrails/roles.yml +5 -0
- data/server/files/etc/environment +2 -0
- data/server/files/etc/god/app.god +35 -0
- data/server/files/etc/god/db.god +17 -0
- data/server/files/etc/god/examples/have_god_daemonize.god +18 -0
- data/server/files/etc/god/master.conf +35 -0
- data/server/files/etc/god/memcache.god +15 -0
- data/server/files/etc/god/notifications.god +14 -0
- data/server/files/etc/god/system.god +34 -0
- data/server/files/etc/god/web.god +36 -0
- data/server/files/etc/init.d/ec2-every-startup +29 -0
- data/server/files/etc/init.d/ec2-first-startup +36 -0
- data/server/files/etc/init.d/god +42 -0
- data/server/files/etc/init.d/nginx +78 -0
- data/server/files/etc/init.d/set_roles +3 -0
- data/server/files/etc/logrotate.d/apache2 +16 -0
- data/server/files/etc/logrotate.d/mongrel +11 -0
- data/server/files/etc/logrotate.d/nginx +11 -0
- data/server/files/etc/memcached.conf +47 -0
- data/server/files/etc/mongrel_cluster/app.yml +9 -0
- data/server/files/etc/motd.tail +13 -0
- data/server/files/etc/mysql/my.cnf +152 -0
- data/server/files/etc/nginx/nginx.conf +296 -0
- data/server/files/etc/postfix/main.cf +4 -0
- data/server/files/etc/rcS.d/S91ec2-first-startup +1 -0
- data/server/files/etc/rcS.d/S92ec2-every-startup +1 -0
- data/server/files/etc/rcS.d/S99set_roles +1 -0
- data/server/files/etc/ssh/sshd_config +94 -0
- data/server/files/etc/sudoers +1 -0
- data/server/files/etc/sudoers.full_access +26 -0
- data/server/files/etc/sudoers.restricted_access +28 -0
- data/server/files/etc/syslog.conf +69 -0
- data/server/files/usr/bin/god +26 -0
- data/server/files/usr/local/ec2onrails/COPYING +339 -0
- data/server/files/usr/local/ec2onrails/bin/archive_file.rb +44 -0
- data/server/files/usr/local/ec2onrails/bin/backup_app_db.rb +159 -0
- data/server/files/usr/local/ec2onrails/bin/ec2_meta_data.rb +80 -0
- data/server/files/usr/local/ec2onrails/bin/exec_runner +73 -0
- data/server/files/usr/local/ec2onrails/bin/init_services.rb +64 -0
- data/server/files/usr/local/ec2onrails/bin/optimize_mysql.rb +348 -0
- data/server/files/usr/local/ec2onrails/bin/rails_env +35 -0
- data/server/files/usr/local/ec2onrails/bin/rebundle.sh +70 -0
- data/server/files/usr/local/ec2onrails/bin/restore_app_db.rb +58 -0
- data/server/files/usr/local/ec2onrails/bin/set_rails_env +40 -0
- data/server/files/usr/local/ec2onrails/bin/set_roles.rb +87 -0
- data/server/files/usr/local/ec2onrails/bin/setup_web_proxy.rb +109 -0
- data/server/files/usr/local/ec2onrails/config +30 -0
- data/server/files/usr/local/ec2onrails/lib/aws_helper.rb +76 -0
- data/server/files/usr/local/ec2onrails/lib/god_helper.rb +129 -0
- data/server/files/usr/local/ec2onrails/lib/god_patch.rb +43 -0
- data/server/files/usr/local/ec2onrails/lib/mysql_helper.rb +101 -0
- data/server/files/usr/local/ec2onrails/lib/roles_helper.rb +151 -0
- data/server/files/usr/local/ec2onrails/lib/s3_helper.rb +99 -0
- data/server/files/usr/local/ec2onrails/lib/utils.rb +16 -0
- data/server/files/usr/local/ec2onrails/lib/vendor/ini.rb +268 -0
- data/server/files/usr/local/ec2onrails/startup-scripts/every-startup/get-hostname.sh +25 -0
- data/server/files/usr/local/ec2onrails/startup-scripts/first-startup/README +5 -0
- data/server/files/usr/local/ec2onrails/startup-scripts/first-startup/create-dirs.sh +39 -0
- data/server/files/usr/local/ec2onrails/startup-scripts/first-startup/generate-default-web-cert-and-key.sh +49 -0
- data/server/files/usr/local/ec2onrails/startup-scripts/first-startup/misc.sh +27 -0
- data/server/files/usr/local/ec2onrails/startup-scripts/first-startup/prepare-mysql-data-dir.sh +24 -0
- data/server/files/usr/local/ec2onrails/startup-scripts/first-startup/setup-credentials.sh +29 -0
- data/server/files/usr/local/ec2onrails/startup-scripts/first-startup/setup-file-permissions.sh +30 -0
- data/server/rakefile.rb +248 -0
- data/setup.rb +1585 -0
- data/test/autobench.conf +60 -0
- data/test/spec/lib/s3_helper_spec.rb +134 -0
- data/test/spec/lib/s3_old.yml +3 -0
- data/test/spec/test_files/test1 +0 -0
- data/test/spec/test_files/test2 +0 -0
- data/test/test_app/Capfile +3 -0
- data/test/test_app/README +182 -0
- data/test/test_app/Rakefile +10 -0
- data/test/test_app/app/controllers/application.rb +7 -0
- data/test/test_app/app/controllers/db_fast_controller.rb +6 -0
- data/test/test_app/app/controllers/fast_controller.rb +5 -0
- data/test/test_app/app/controllers/slow_controller.rb +6 -0
- data/test/test_app/app/controllers/very_slow_controller.rb +6 -0
- data/test/test_app/app/helpers/application_helper.rb +3 -0
- data/test/test_app/app/helpers/db_fast_helper.rb +2 -0
- data/test/test_app/app/helpers/fast_helper.rb +2 -0
- data/test/test_app/app/helpers/slow_helper.rb +2 -0
- data/test/test_app/app/helpers/very_slow_helper.rb +2 -0
- data/test/test_app/config/boot.rb +109 -0
- data/test/test_app/config/database.yml +19 -0
- data/test/test_app/config/deploy.rb +21 -0
- data/test/test_app/config/environment.rb +60 -0
- data/test/test_app/config/environments/development.rb +21 -0
- data/test/test_app/config/environments/production.rb +18 -0
- data/test/test_app/config/environments/test.rb +19 -0
- data/test/test_app/config/routes.rb +27 -0
- data/test/test_app/db/schema.rb +7 -0
- data/test/test_app/doc/README_FOR_APP +2 -0
- data/test/test_app/public/404.html +30 -0
- data/test/test_app/public/500.html +30 -0
- data/test/test_app/public/dispatch.cgi +10 -0
- data/test/test_app/public/dispatch.fcgi +24 -0
- data/test/test_app/public/dispatch.rb +10 -0
- data/test/test_app/public/favicon.ico +0 -0
- data/test/test_app/public/images/rails.png +0 -0
- data/test/test_app/public/javascripts/application.js +2 -0
- data/test/test_app/public/javascripts/controls.js +963 -0
- data/test/test_app/public/javascripts/dragdrop.js +972 -0
- data/test/test_app/public/javascripts/effects.js +1120 -0
- data/test/test_app/public/javascripts/prototype.js +4225 -0
- data/test/test_app/public/robots.txt +1 -0
- data/test/test_app/script/about +3 -0
- data/test/test_app/script/breakpointer +3 -0
- data/test/test_app/script/console +3 -0
- data/test/test_app/script/destroy +3 -0
- data/test/test_app/script/generate +3 -0
- data/test/test_app/script/performance/benchmarker +3 -0
- data/test/test_app/script/performance/profiler +3 -0
- data/test/test_app/script/performance/request +3 -0
- data/test/test_app/script/plugin +3 -0
- data/test/test_app/script/process/inspector +3 -0
- data/test/test_app/script/process/reaper +3 -0
- data/test/test_app/script/process/spawner +3 -0
- data/test/test_app/script/runner +3 -0
- data/test/test_app/script/server +3 -0
- data/test/test_app/test/functional/db_fast_controller_test.rb +18 -0
- data/test/test_app/test/functional/fast_controller_test.rb +18 -0
- data/test/test_app/test/functional/slow_controller_test.rb +18 -0
- data/test/test_app/test/functional/very_slow_controller_test.rb +18 -0
- data/test/test_app/test/test_helper.rb +28 -0
- data/test/test_ec2onrails.rb +11 -0
- data/test/test_helper.rb +2 -0
- metadata +274 -0
data/ec2onrails.gemspec
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
Gem::Specification.new do |s|
|
|
2
|
+
s.name = %q{ec2onrails}
|
|
3
|
+
s.version = "0.9.10"
|
|
4
|
+
|
|
5
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
|
6
|
+
s.authors = ["Paul Dowman, Adam Greene"]
|
|
7
|
+
s.date = %q{2008-12-19}
|
|
8
|
+
s.description = %q{Client-side libraries (Capistrano tasks) for managing and deploying to EC2 on Rails servers.}
|
|
9
|
+
s.email = %q{paul@pauldowman.com}
|
|
10
|
+
s.extra_rdoc_files = ["CHANGELOG", "lib/ec2onrails/capistrano_utils.rb", "lib/ec2onrails/recipes.rb", "lib/ec2onrails/version.rb", "lib/ec2onrails.rb", "README.textile"]
|
|
11
|
+
s.files = ["CHANGELOG", "COPYING", "ec2onrails.gemspec", "examples/Capfile", "examples/deploy.rb", "examples/s3.yml", "lib/ec2onrails/capistrano_utils.rb", "lib/ec2onrails/recipes.rb", "lib/ec2onrails/version.rb", "lib/ec2onrails.rb", "Manifest", "Rakefile", "README.textile", "server/build-ec2onrails.sh", "server/files/etc/aliases", "server/files/etc/aliases.db", "server/files/etc/apache2/apache2.conf", "server/files/etc/apache2/conf.d/app.proxy_cluster.conf", "server/files/etc/apache2/conf.d/app.proxy_frontend.conf", "server/files/etc/apache2/mods-available/proxy.conf", "server/files/etc/apache2/sites-available/app.common", "server/files/etc/apache2/sites-available/app.custom", "server/files/etc/apache2/sites-available/default", "server/files/etc/apache2/sites-available/default-ssl", "server/files/etc/cron.d/backup_app_db_to_s3", "server/files/etc/cron.daily/app", "server/files/etc/cron.daily/logrotate_post", "server/files/etc/cron.hourly/app", "server/files/etc/cron.monthly/app", "server/files/etc/cron.weekly/app", "server/files/etc/denyhosts.conf", "server/files/etc/dpkg/dpkg.cfg", "server/files/etc/ec2onrails/balancer_members", "server/files/etc/ec2onrails/README", "server/files/etc/ec2onrails/roles.yml", "server/files/etc/environment", "server/files/etc/god/app.god", "server/files/etc/god/db.god", "server/files/etc/god/examples/have_god_daemonize.god", "server/files/etc/god/master.conf", "server/files/etc/god/memcache.god", "server/files/etc/god/notifications.god", "server/files/etc/god/system.god", "server/files/etc/god/web.god", "server/files/etc/init.d/ec2-every-startup", "server/files/etc/init.d/ec2-first-startup", "server/files/etc/init.d/god", "server/files/etc/init.d/nginx", "server/files/etc/init.d/set_roles", "server/files/etc/logrotate.d/apache2", "server/files/etc/logrotate.d/mongrel", "server/files/etc/logrotate.d/nginx", "server/files/etc/memcached.conf", "server/files/etc/mongrel_cluster/app.yml", "server/files/etc/motd.tail", "server/files/etc/mysql/my.cnf", "server/files/etc/nginx/nginx.conf", "server/files/etc/postfix/main.cf", "server/files/etc/rcS.d/S91ec2-first-startup", "server/files/etc/rcS.d/S92ec2-every-startup", "server/files/etc/rcS.d/S99set_roles", "server/files/etc/ssh/sshd_config", "server/files/etc/sudoers", "server/files/etc/sudoers.full_access", "server/files/etc/sudoers.restricted_access", "server/files/etc/syslog.conf", "server/files/usr/bin/god", "server/files/usr/local/ec2onrails/bin/archive_file.rb", "server/files/usr/local/ec2onrails/bin/backup_app_db.rb", "server/files/usr/local/ec2onrails/bin/ec2_meta_data.rb", "server/files/usr/local/ec2onrails/bin/exec_runner", "server/files/usr/local/ec2onrails/bin/init_services.rb", "server/files/usr/local/ec2onrails/bin/optimize_mysql.rb", "server/files/usr/local/ec2onrails/bin/rails_env", "server/files/usr/local/ec2onrails/bin/rebundle.sh", "server/files/usr/local/ec2onrails/bin/restore_app_db.rb", "server/files/usr/local/ec2onrails/bin/set_rails_env", "server/files/usr/local/ec2onrails/bin/set_roles.rb", "server/files/usr/local/ec2onrails/bin/setup_web_proxy.rb", "server/files/usr/local/ec2onrails/config", "server/files/usr/local/ec2onrails/COPYING", "server/files/usr/local/ec2onrails/lib/aws_helper.rb", "server/files/usr/local/ec2onrails/lib/god_helper.rb", "server/files/usr/local/ec2onrails/lib/god_patch.rb", "server/files/usr/local/ec2onrails/lib/mysql_helper.rb", "server/files/usr/local/ec2onrails/lib/roles_helper.rb", "server/files/usr/local/ec2onrails/lib/s3_helper.rb", "server/files/usr/local/ec2onrails/lib/utils.rb", "server/files/usr/local/ec2onrails/lib/vendor/ini.rb", "server/files/usr/local/ec2onrails/startup-scripts/every-startup/get-hostname.sh", "server/files/usr/local/ec2onrails/startup-scripts/first-startup/create-dirs.sh", "server/files/usr/local/ec2onrails/startup-scripts/first-startup/generate-default-web-cert-and-key.sh", "server/files/usr/local/ec2onrails/startup-scripts/first-startup/misc.sh", "server/files/usr/local/ec2onrails/startup-scripts/first-startup/prepare-mysql-data-dir.sh", "server/files/usr/local/ec2onrails/startup-scripts/first-startup/README", "server/files/usr/local/ec2onrails/startup-scripts/first-startup/setup-credentials.sh", "server/files/usr/local/ec2onrails/startup-scripts/first-startup/setup-file-permissions.sh", "server/rakefile.rb", "setup.rb", "test/autobench.conf", "test/spec/lib/s3_helper_spec.rb", "test/spec/lib/s3_old.yml", "test/spec/test_files/test1", "test/spec/test_files/test2", "test/test_app/app/controllers/application.rb", "test/test_app/app/controllers/db_fast_controller.rb", "test/test_app/app/controllers/fast_controller.rb", "test/test_app/app/controllers/slow_controller.rb", "test/test_app/app/controllers/very_slow_controller.rb", "test/test_app/app/helpers/application_helper.rb", "test/test_app/app/helpers/db_fast_helper.rb", "test/test_app/app/helpers/fast_helper.rb", "test/test_app/app/helpers/slow_helper.rb", "test/test_app/app/helpers/very_slow_helper.rb", "test/test_app/Capfile", "test/test_app/config/boot.rb", "test/test_app/config/database.yml", "test/test_app/config/deploy.rb", "test/test_app/config/environment.rb", "test/test_app/config/environments/development.rb", "test/test_app/config/environments/production.rb", "test/test_app/config/environments/test.rb", "test/test_app/config/routes.rb", "test/test_app/db/schema.rb", "test/test_app/doc/README_FOR_APP", "test/test_app/public/404.html", "test/test_app/public/500.html", "test/test_app/public/dispatch.cgi", "test/test_app/public/dispatch.fcgi", "test/test_app/public/dispatch.rb", "test/test_app/public/favicon.ico", "test/test_app/public/images/rails.png", "test/test_app/public/javascripts/application.js", "test/test_app/public/javascripts/controls.js", "test/test_app/public/javascripts/dragdrop.js", "test/test_app/public/javascripts/effects.js", "test/test_app/public/javascripts/prototype.js", "test/test_app/public/robots.txt", "test/test_app/Rakefile", "test/test_app/README", "test/test_app/script/about", "test/test_app/script/breakpointer", "test/test_app/script/console", "test/test_app/script/destroy", "test/test_app/script/generate", "test/test_app/script/performance/benchmarker", "test/test_app/script/performance/profiler", "test/test_app/script/performance/request", "test/test_app/script/plugin", "test/test_app/script/process/inspector", "test/test_app/script/process/reaper", "test/test_app/script/process/spawner", "test/test_app/script/runner", "test/test_app/script/server", "test/test_app/test/functional/db_fast_controller_test.rb", "test/test_app/test/functional/fast_controller_test.rb", "test/test_app/test/functional/slow_controller_test.rb", "test/test_app/test/functional/very_slow_controller_test.rb", "test/test_app/test/test_helper.rb", "test/test_ec2onrails.rb", "test/test_helper.rb", "TODO"]
|
|
12
|
+
s.has_rdoc = true
|
|
13
|
+
s.homepage = %q{http://ec2onrails.rubyforge.org}
|
|
14
|
+
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Ec2onrails", "--main", "README.textile"]
|
|
15
|
+
s.require_paths = ["lib"]
|
|
16
|
+
s.rubyforge_project = %q{ec2onrails}
|
|
17
|
+
s.rubygems_version = %q{1.3.1}
|
|
18
|
+
s.summary = %q{Client-side libraries (Capistrano tasks) for managing and deploying to EC2 on Rails servers.}
|
|
19
|
+
s.test_files = ["test/test_app/test/functional/db_fast_controller_test.rb", "test/test_app/test/functional/fast_controller_test.rb", "test/test_app/test/functional/slow_controller_test.rb", "test/test_app/test/functional/very_slow_controller_test.rb", "test/test_app/test/test_helper.rb", "test/test_ec2onrails.rb", "test/test_helper.rb"]
|
|
20
|
+
|
|
21
|
+
if s.respond_to? :specification_version then
|
|
22
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
|
23
|
+
s.specification_version = 2
|
|
24
|
+
|
|
25
|
+
if current_version >= 3 then
|
|
26
|
+
s.add_runtime_dependency(%q<capistrano>, [">= 0", "= 2.4.3"])
|
|
27
|
+
s.add_runtime_dependency(%q<archive-tar-minitar>, [">= 0", "= 0.5.2"])
|
|
28
|
+
s.add_runtime_dependency(%q<optiflag>, [">= 0", "= 0.6.5"])
|
|
29
|
+
s.add_development_dependency(%q<rake>, [">= 0.7.1"])
|
|
30
|
+
else
|
|
31
|
+
s.add_dependency(%q<capistrano>, [">= 0", "= 2.4.3"])
|
|
32
|
+
s.add_dependency(%q<archive-tar-minitar>, [">= 0", "= 0.5.2"])
|
|
33
|
+
s.add_dependency(%q<optiflag>, [">= 0", "= 0.6.5"])
|
|
34
|
+
s.add_dependency(%q<rake>, [">= 0.7.1"])
|
|
35
|
+
end
|
|
36
|
+
else
|
|
37
|
+
s.add_dependency(%q<capistrano>, [">= 0", "= 2.4.3"])
|
|
38
|
+
s.add_dependency(%q<archive-tar-minitar>, [">= 0", "= 0.5.2"])
|
|
39
|
+
s.add_dependency(%q<optiflag>, [">= 0", "= 0.6.5"])
|
|
40
|
+
s.add_dependency(%q<rake>, [">= 0.7.1"])
|
|
41
|
+
end
|
|
42
|
+
end
|
data/examples/Capfile
ADDED
data/examples/deploy.rb
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
# This is a sample Capistrano config file for EC2 on Rails.
|
|
2
|
+
# It should be edited and customized.
|
|
3
|
+
|
|
4
|
+
set :application, "yourapp"
|
|
5
|
+
|
|
6
|
+
set :repository, "http://svn.foo.com/svn/#{application}/trunk"
|
|
7
|
+
|
|
8
|
+
# NOTE: for some reason Capistrano requires you to have both the public and
|
|
9
|
+
# the private key in the same folder, the public key should have the
|
|
10
|
+
# extension ".pub".
|
|
11
|
+
ssh_options[:keys] = ["#{ENV['HOME']}/.ssh/your-ec2-key"]
|
|
12
|
+
|
|
13
|
+
# Your EC2 instances. Use the ec2-xxx....amazonaws.com hostname, not
|
|
14
|
+
# any other name (in case you have your own DNS alias) or it won't
|
|
15
|
+
# be able to resolve to the internal IP address.
|
|
16
|
+
role :web, "ec2-12-xx-xx-xx.z-1.compute-1.amazonaws.com"
|
|
17
|
+
role :app, "ec2-34-xx-xx-xx.z-1.compute-1.amazonaws.com"
|
|
18
|
+
role :memcache, "ec2-12-xx-xx-xx.z-1.compute-1.amazonaws.com"
|
|
19
|
+
role :db, "ec2-56-xx-xx-xx.z-1.compute-1.amazonaws.com", :primary => true
|
|
20
|
+
# role :db, "ec2-56-xx-xx-xx.z-1.compute-1.amazonaws.com", :primary => true, :ebs_vol_id => 'vol-12345abc'
|
|
21
|
+
# optinally, you can specify Amazon's EBS volume ID if the database is persisted
|
|
22
|
+
# via Amazon's EBS. See the main README for more information.
|
|
23
|
+
|
|
24
|
+
# Whatever you set here will be taken set as the default RAILS_ENV value
|
|
25
|
+
# on the server. Your app and your hourly/daily/weekly/monthly scripts
|
|
26
|
+
# will run with RAILS_ENV set to this value.
|
|
27
|
+
set :rails_env, "production"
|
|
28
|
+
|
|
29
|
+
# EC2 on Rails config.
|
|
30
|
+
# NOTE: Some of these should be omitted if not needed.
|
|
31
|
+
set :ec2onrails_config, {
|
|
32
|
+
# S3 bucket and "subdir" used by the ec2onrails:db:restore task
|
|
33
|
+
# NOTE: this only applies if you are not using EBS
|
|
34
|
+
:restore_from_bucket => "your-bucket",
|
|
35
|
+
:restore_from_bucket_subdir => "database",
|
|
36
|
+
|
|
37
|
+
# S3 bucket and "subdir" used by the ec2onrails:db:archive task
|
|
38
|
+
# This does not affect the automatic backup of your MySQL db to S3, it's
|
|
39
|
+
# just for manually archiving a db snapshot to a different bucket if
|
|
40
|
+
# desired.
|
|
41
|
+
# NOTE: this only applies if you are not using EBS
|
|
42
|
+
:archive_to_bucket => "your-other-bucket",
|
|
43
|
+
:archive_to_bucket_subdir => "db-archive/#{Time.new.strftime('%Y-%m-%d--%H-%M-%S')}",
|
|
44
|
+
|
|
45
|
+
# Set a root password for MySQL. Run "cap ec2onrails:db:set_root_password"
|
|
46
|
+
# to enable this. This is optional, and after doing this the
|
|
47
|
+
# ec2onrails:db:drop task won't work, but be aware that MySQL accepts
|
|
48
|
+
# connections on the public network interface (you should block the MySQL
|
|
49
|
+
# port with the firewall anyway).
|
|
50
|
+
# If you don't care about setting the mysql root password then remove this.
|
|
51
|
+
:mysql_root_password => "your-mysql-root-password",
|
|
52
|
+
|
|
53
|
+
# Any extra Ubuntu packages to install if desired
|
|
54
|
+
# If you don't want to install extra packages then remove this.
|
|
55
|
+
:packages => ["logwatch", "imagemagick"],
|
|
56
|
+
|
|
57
|
+
# Any extra RubyGems to install if desired: can be "gemname" or if a
|
|
58
|
+
# particular version is desired "gemname -v 1.0.1"
|
|
59
|
+
# If you don't want to install extra rubygems then remove this
|
|
60
|
+
# NOTE: if you are using rails 2.1, ec2onrails calls 'sudo rake gem:install',
|
|
61
|
+
# which will install gems defined in your rails configuration
|
|
62
|
+
:rubygems => ["rmagick", "rfacebook -v 0.9.7"],
|
|
63
|
+
|
|
64
|
+
# Defines the web proxy that will be used. Choices are :apache or :nginx
|
|
65
|
+
:web_proxy_server => :apache,
|
|
66
|
+
|
|
67
|
+
# extra security measures are taken if this is true, BUT it makes initial
|
|
68
|
+
# experimentation and setup a bit tricky. For example, if you do not
|
|
69
|
+
# have your ssh keys setup correctly, you will be locked out of your
|
|
70
|
+
# server after 3 attempts for upto 3 months.
|
|
71
|
+
:harden_server => false,
|
|
72
|
+
|
|
73
|
+
# Set the server timezone. run "cap -e ec2onrails:server:set_timezone" for
|
|
74
|
+
# details
|
|
75
|
+
:timezone => "UTC",
|
|
76
|
+
|
|
77
|
+
# Files to deploy to the server (they'll be owned by root). It's intended
|
|
78
|
+
# mainly for customized config files for new packages installed via the
|
|
79
|
+
# ec2onrails:server:install_packages task. Subdirectories and files inside
|
|
80
|
+
# here will be placed in the same structure relative to the root of the
|
|
81
|
+
# server's filesystem.
|
|
82
|
+
# If you don't need to deploy customized config files to the server then
|
|
83
|
+
# remove this.
|
|
84
|
+
:server_config_files_root => "../server_config",
|
|
85
|
+
|
|
86
|
+
# If config files are deployed, some services might need to be restarted.
|
|
87
|
+
# If you don't need to deploy customized config files to the server then
|
|
88
|
+
# remove this.
|
|
89
|
+
:services_to_restart => %w(postfix sysklogd),
|
|
90
|
+
|
|
91
|
+
# Set an email address to forward admin mail messages to. If you don't
|
|
92
|
+
# want to receive mail from the server (e.g. monit alert messages) then
|
|
93
|
+
# remove this.
|
|
94
|
+
:mail_forward_address => "you@yourdomain.com",
|
|
95
|
+
|
|
96
|
+
# Set this if you want SSL to be enabled on the web server. The SSL cert
|
|
97
|
+
# and key files need to exist on the server, The cert file should be in
|
|
98
|
+
# /etc/ssl/certs/default.pem and the key file should be in
|
|
99
|
+
# /etc/ssl/private/default.key (see :server_config_files_root).
|
|
100
|
+
:enable_ssl => true
|
|
101
|
+
}
|
data/examples/s3.yml
ADDED
data/lib/ec2onrails.rb
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# This file is part of EC2 on Rails.
|
|
2
|
+
# http://rubyforge.org/projects/ec2onrails/
|
|
3
|
+
#
|
|
4
|
+
# Copyright 2007 Paul Dowman, http://pauldowman.com/
|
|
5
|
+
#
|
|
6
|
+
# EC2 on Rails is free software; you can redistribute it and/or modify
|
|
7
|
+
# it under the terms of the GNU General Public License as published by
|
|
8
|
+
# the Free Software Foundation; either version 2 of the License, or
|
|
9
|
+
# (at your option) any later version.
|
|
10
|
+
#
|
|
11
|
+
# EC2 on Rails is distributed in the hope that it will be useful,
|
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
14
|
+
# GNU General Public License for more details.
|
|
15
|
+
#
|
|
16
|
+
# You should have received a copy of the GNU General Public License
|
|
17
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
$:.unshift File.dirname(__FILE__)
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
module Ec2onrails
|
|
2
|
+
module CapistranoUtils
|
|
3
|
+
def run_local(command)
|
|
4
|
+
result = system command
|
|
5
|
+
raise("error: #{$?}") unless result
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def run_init_script(script, arg)
|
|
9
|
+
# since init scripts might have the execute bit unset by the set_roles script we need to check
|
|
10
|
+
sudo "sh -c 'if [ -x /etc/init.d/#{script} ] ; then /etc/init.d/#{script} #{arg}; fi'"
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# return hostnames for the role named role_sym that has the specified options
|
|
14
|
+
def hostnames_for_role(role_sym, options = {})
|
|
15
|
+
role = roles[role_sym]
|
|
16
|
+
unless role
|
|
17
|
+
return []
|
|
18
|
+
end
|
|
19
|
+
# make sure we match the server with all the passed in options, BUT the server can
|
|
20
|
+
# have additional options defined. e.g.: :primary => true and :ebs_vol_id => 'vol-1234abcd'
|
|
21
|
+
# but we want to select the server where :primary => true
|
|
22
|
+
role.select{|s|
|
|
23
|
+
match = true
|
|
24
|
+
options.each_pair{|k,v| match = false if s.options[k] != v}
|
|
25
|
+
}.collect{|s| s.host}
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Like the capture method, but does not print out error stream and swallows
|
|
29
|
+
# an exception if the process's exit code != 0
|
|
30
|
+
def quiet_capture(command, options={})
|
|
31
|
+
output = ""
|
|
32
|
+
invoke_command(command, options.merge(:once => true)) do |ch, stream, data|
|
|
33
|
+
case stream
|
|
34
|
+
when :out then output << data
|
|
35
|
+
# when :err then warn "[err :: #{ch[:server]}] #{data}"
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
ensure
|
|
39
|
+
return (output || '').strip
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,844 @@
|
|
|
1
|
+
# This file is part of EC2 on Rails.
|
|
2
|
+
# http://rubyforge.org/projects/ec2onrails/
|
|
3
|
+
#
|
|
4
|
+
# Copyright 2007 Paul Dowman, http://pauldowman.com/
|
|
5
|
+
#
|
|
6
|
+
# EC2 on Rails is free software; you can redistribute it and/or modify
|
|
7
|
+
# it under the terms of the GNU General Public License as published by
|
|
8
|
+
# the Free Software Foundation; either version 2 of the License, or
|
|
9
|
+
# (at your option) any later version.
|
|
10
|
+
#
|
|
11
|
+
# EC2 on Rails is distributed in the hope that it will be useful,
|
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
14
|
+
# GNU General Public License for more details.
|
|
15
|
+
#
|
|
16
|
+
# You should have received a copy of the GNU General Public License
|
|
17
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
18
|
+
|
|
19
|
+
require 'fileutils'
|
|
20
|
+
include FileUtils
|
|
21
|
+
require 'tmpdir'
|
|
22
|
+
require 'pp'
|
|
23
|
+
require 'zlib'
|
|
24
|
+
require 'archive/tar/minitar'
|
|
25
|
+
include Archive::Tar
|
|
26
|
+
|
|
27
|
+
require 'ec2onrails/version'
|
|
28
|
+
require 'ec2onrails/capistrano_utils'
|
|
29
|
+
include Ec2onrails::CapistranoUtils
|
|
30
|
+
|
|
31
|
+
Capistrano::Configuration.instance.load do
|
|
32
|
+
|
|
33
|
+
unless ec2onrails_config
|
|
34
|
+
raise "ec2onrails_config variable not set. (It should be a hash.)"
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
cfg = ec2onrails_config
|
|
38
|
+
|
|
39
|
+
#:apache or :nginx
|
|
40
|
+
cfg[:web_proxy_server] ||= :apache
|
|
41
|
+
|
|
42
|
+
set :ec2onrails_version, Ec2onrails::VERSION::STRING
|
|
43
|
+
set :image_id_32_bit, Ec2onrails::VERSION::AMI_ID_32_BIT
|
|
44
|
+
set :image_id_64_bit, Ec2onrails::VERSION::AMI_ID_64_BIT
|
|
45
|
+
set :deploy_to, "/mnt/app"
|
|
46
|
+
set :use_sudo, false
|
|
47
|
+
set :user, "app"
|
|
48
|
+
|
|
49
|
+
#in case any changes were made to the configs, like changing the number of mongrels
|
|
50
|
+
before "deploy:cold", "ec2onrails:server:grant_sudo_access"
|
|
51
|
+
after "deploy:symlink", "ec2onrails:server:set_roles", "ec2onrails:server:init_services"
|
|
52
|
+
after "deploy:cold", "ec2onrails:db:init_backup", "ec2onrails:db:optimize", "ec2onrails:server:restrict_sudo_access"
|
|
53
|
+
after "ec2onrails:server:install_gems", "ec2onrails:server:add_gem_sources"
|
|
54
|
+
|
|
55
|
+
#NOTE: some default setups (like engineyard's) do some symlinking of config files after
|
|
56
|
+
# deploy:update_code. The ordering here matters as we need to have those symlinks in place
|
|
57
|
+
# but we need to have the gems in place before the rails env is loaded up, or else it will
|
|
58
|
+
# fail. By adding it to the callback queue AFTER all the tasks have loaded up, we make sure
|
|
59
|
+
# it is done at the very end.
|
|
60
|
+
#
|
|
61
|
+
# *IF* you had tasks also triggered after update_code that run rake tasks
|
|
62
|
+
# (like compressing javascript and stylesheets), move those over to before "deploy:symlink"
|
|
63
|
+
# and you'll be set!
|
|
64
|
+
on :load do
|
|
65
|
+
after "deploy:update_code", "ec2onrails:server:run_rails_rake_gems_install"
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
# override default start/stop/restart tasks
|
|
70
|
+
namespace :deploy do
|
|
71
|
+
desc <<-DESC
|
|
72
|
+
Overrides the default Capistrano deploy:start, uses \
|
|
73
|
+
'god start app'
|
|
74
|
+
DESC
|
|
75
|
+
task :start, :roles => :app do
|
|
76
|
+
sudo "god start app"
|
|
77
|
+
# sudo "god monitor app"
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
desc <<-DESC
|
|
81
|
+
Overrides the default Capistrano deploy:stop, uses \
|
|
82
|
+
'god stop app'
|
|
83
|
+
DESC
|
|
84
|
+
task :stop, :roles => :app do
|
|
85
|
+
# sudo "god unmonitor app"
|
|
86
|
+
sudo "god stop app"
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
desc <<-DESC
|
|
90
|
+
Overrides the default Capistrano deploy:restart, uses \
|
|
91
|
+
'god restart app'
|
|
92
|
+
DESC
|
|
93
|
+
task :restart, :roles => :app do
|
|
94
|
+
sudo "god restart app"
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
namespace :ec2onrails do
|
|
99
|
+
desc <<-DESC
|
|
100
|
+
Show the AMI id's of the current images for this version of \
|
|
101
|
+
EC2 on Rails.
|
|
102
|
+
DESC
|
|
103
|
+
task :ami_ids do
|
|
104
|
+
puts "32-bit server image for EC2 on Rails #{ec2onrails_version}: #{image_id_32_bit}"
|
|
105
|
+
puts "64-bit server image for EC2 on Rails #{ec2onrails_version}: #{image_id_64_bit}"
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
desc <<-DESC
|
|
109
|
+
Copies the public key from the server using the external "ssh"
|
|
110
|
+
command because Net::SSH, which is used by Capistrano, needs it.
|
|
111
|
+
This will only work if you have an ssh command in the path.
|
|
112
|
+
If Capistrano can successfully connect to your EC2 instance you
|
|
113
|
+
don't need to do this. It will copy from the first server in the
|
|
114
|
+
:app role, this can be overridden by specifying the HOST
|
|
115
|
+
environment variable
|
|
116
|
+
DESC
|
|
117
|
+
task :get_public_key_from_server do
|
|
118
|
+
host = find_servers_for_task(current_task).first.host
|
|
119
|
+
privkey = ssh_options[:keys][0]
|
|
120
|
+
pubkey = "#{privkey}.pub"
|
|
121
|
+
msg = <<-MSG
|
|
122
|
+
Your first key in ssh_options[:keys] is #{privkey}, presumably that's
|
|
123
|
+
your EC2 private key. The public key will be copied from the server
|
|
124
|
+
named '#{host}' and saved locally as #{pubkey}. Continue? [y/n]
|
|
125
|
+
MSG
|
|
126
|
+
choice = nil
|
|
127
|
+
while choice != "y" && choice != "n"
|
|
128
|
+
choice = Capistrano::CLI.ui.ask(msg).downcase
|
|
129
|
+
msg = "Please enter 'y' or 'n'."
|
|
130
|
+
end
|
|
131
|
+
if choice == "y"
|
|
132
|
+
run_local "scp -i '#{privkey}' app@#{host}:.ssh/authorized_keys #{pubkey}"
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
desc <<-DESC
|
|
137
|
+
Prepare a newly-started instance for a cold deploy.
|
|
138
|
+
DESC
|
|
139
|
+
task :setup do
|
|
140
|
+
ec2onrails.server.allow_sudo do
|
|
141
|
+
server.set_mail_forward_address
|
|
142
|
+
server.set_timezone
|
|
143
|
+
server.install_packages
|
|
144
|
+
server.install_gems
|
|
145
|
+
server.deploy_files
|
|
146
|
+
server.setup_web_proxy
|
|
147
|
+
server.set_roles
|
|
148
|
+
server.enable_ssl if cfg[:enable_ssl]
|
|
149
|
+
server.set_rails_env
|
|
150
|
+
server.restart_services
|
|
151
|
+
deploy.setup
|
|
152
|
+
db.create
|
|
153
|
+
server.harden_server
|
|
154
|
+
db.enable_ebs
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
desc <<-DESC
|
|
159
|
+
Deploy and restore database from S3
|
|
160
|
+
DESC
|
|
161
|
+
task :restore_db_and_deploy do
|
|
162
|
+
db.recreate
|
|
163
|
+
deploy.update_code
|
|
164
|
+
deploy.symlink
|
|
165
|
+
db.restore
|
|
166
|
+
deploy.migrations
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
namespace :ec2 do
|
|
170
|
+
desc <<-DESC
|
|
171
|
+
DESC
|
|
172
|
+
task :configure_firewall do
|
|
173
|
+
# TODO
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
namespace :db do
|
|
178
|
+
desc <<-DESC
|
|
179
|
+
[internal] Load configuration info for the database from
|
|
180
|
+
config/database.yml, and start mysql (it must be running
|
|
181
|
+
in order to interact with it).
|
|
182
|
+
DESC
|
|
183
|
+
task :load_config do
|
|
184
|
+
unless hostnames_for_role(:db, :primary => true).empty?
|
|
185
|
+
db_config = YAML::load(ERB.new(File.read("config/database.yml")).result)[rails_env.to_s] || {}
|
|
186
|
+
cfg[:db_name] ||= db_config['database']
|
|
187
|
+
cfg[:db_user] ||= db_config['username'] || db_config['user']
|
|
188
|
+
cfg[:db_password] ||= db_config['password']
|
|
189
|
+
cfg[:db_host] ||= db_config['host']
|
|
190
|
+
cfg[:db_port] ||= db_config['port']
|
|
191
|
+
cfg[:db_socket] ||= db_config['socket']
|
|
192
|
+
|
|
193
|
+
if (cfg[:db_host].nil? || cfg[:db_host].empty?) && (cfg[:db_socket].nil? || cfg[:db_socket].empty?)
|
|
194
|
+
raise "ERROR: missing database config. Make sure database.yml contains a '#{rails_env}' section with either 'host: hostname' or 'socket: /var/run/mysqld/mysqld.sock'."
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
[cfg[:db_name], cfg[:db_user], cfg[:db_password]].each do |s|
|
|
198
|
+
if s.nil? || s.empty?
|
|
199
|
+
raise "ERROR: missing database config. Make sure database.yml contains a '#{rails_env}' section with a database name, user, and password."
|
|
200
|
+
elsif s.match(/['"]/)
|
|
201
|
+
raise "ERROR: database config string '#{s}' contains quotes."
|
|
202
|
+
end
|
|
203
|
+
end
|
|
204
|
+
end
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
desc <<-DESC
|
|
208
|
+
Create the MySQL database. Assumes there is no MySQL root \
|
|
209
|
+
password. To create a MySQL root password create a task that's run \
|
|
210
|
+
after this task using an after hook.
|
|
211
|
+
DESC
|
|
212
|
+
task :create, :roles => :db do
|
|
213
|
+
on_rollback { drop }
|
|
214
|
+
load_config
|
|
215
|
+
start
|
|
216
|
+
sleep(5) #make sure the db has some time to start up!
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
# remove the default test database, though sometimes it doesn't exist (perhaps it isn't there anymore?)
|
|
220
|
+
run %{mysql -u root -e "drop database if exists test; flush privileges;"}
|
|
221
|
+
|
|
222
|
+
# removing anonymous mysql accounts
|
|
223
|
+
run %{mysql -u root -D mysql -e "delete from db where User = ''; flush privileges;"}
|
|
224
|
+
run %{mysql -u root -D mysql -e "delete from user where User = ''; flush privileges;"}
|
|
225
|
+
|
|
226
|
+
# qoting of database names allows special characters eg (the-database-name)
|
|
227
|
+
# the quotes need to be double escaped. Once for capistrano and once for the host shell
|
|
228
|
+
run %{mysql -u root -e "create database if not exists \\`#{cfg[:db_name]}\\`;"}
|
|
229
|
+
run %{mysql -u root -e "grant all on \\`#{cfg[:db_name]}\\`.* to '#{cfg[:db_user]}'@'%' identified by '#{cfg[:db_password]}';"}
|
|
230
|
+
run %{mysql -u root -e "grant reload on *.* to '#{cfg[:db_user]}'@'%' identified by '#{cfg[:db_password]}';"}
|
|
231
|
+
run %{mysql -u root -e "grant super on *.* to '#{cfg[:db_user]}'@'%' identified by '#{cfg[:db_password]}';"}
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
desc <<-DESC
|
|
235
|
+
Move the MySQL database to Amazon's Elastic Block Store (EBS), \
|
|
236
|
+
which is a persistant data store for the cloud.
|
|
237
|
+
OPTIONAL PARAMETERS:
|
|
238
|
+
* SIZE: Pass in num in gigs, like 10, to set the size, otherwise it will \
|
|
239
|
+
default to 10 gigs.
|
|
240
|
+
* VOLUME_ID: The volume_id to use for the mysql database
|
|
241
|
+
NOTE: keep track of the volume ID, as you'll want to keep this for your \
|
|
242
|
+
records and probably add it to the :db role in your deploy.rb file \
|
|
243
|
+
(see the ec2onrails sample deploy.rb file for additional information)
|
|
244
|
+
DESC
|
|
245
|
+
task :enable_ebs, :roles => :db, :only => { :primary => true } do
|
|
246
|
+
# based off of Eric's work:
|
|
247
|
+
# http://developer.amazonwebservices.com/connect/entry.jspa?externalID=1663&categoryID=100
|
|
248
|
+
#
|
|
249
|
+
# EXPLAINATION:
|
|
250
|
+
# There is a lot going on here! At the end, the setup should be:
|
|
251
|
+
# * create EBS volume if run outside of the ec2onrails:setup and
|
|
252
|
+
# VOLUME_ID is not passed in when the cap task is called
|
|
253
|
+
# * EBS volume attached to /dev/sdh
|
|
254
|
+
# * format to xfs if new or do a xfs_check if previously existed
|
|
255
|
+
# * mounted on /var/local and update /etc/fstab
|
|
256
|
+
# * move /mnt/mysql_data -> /var/local/mysql_data
|
|
257
|
+
# * move /mnt/log/mysql -> /var/local/log/mysql
|
|
258
|
+
# * change mysql configs by writing /etc/mysql/conf.d/mysql-ec2-ebs.cnf
|
|
259
|
+
# * keep a copy of the mysql configs with the EBS volume, and if that volume is hooked into
|
|
260
|
+
# another instance, make sure the mysql configs that go with that volume are symlinked to /etc/mysql
|
|
261
|
+
# * update the file locations of the mysql binary logs in /mnt/log/mysql/mysql-bin.index
|
|
262
|
+
# * symlink the moved folders to their old position... makes the move to EBS transparent
|
|
263
|
+
# * Amazon doesn't contain EBS information in the meta-data API (yet). So write
|
|
264
|
+
# /etc/ec2onrails/ebs_info.yml
|
|
265
|
+
# to contain the meta-data information that we need
|
|
266
|
+
#
|
|
267
|
+
# DESIGN CONSIDERATIONS
|
|
268
|
+
# * only moving mysql data to EBS. seems the most obvious, and if we move over other components
|
|
269
|
+
# we will have to share that bandwidth (1 Gbps pipe to SAN). So limiting to what we really need
|
|
270
|
+
# * not moving all mysql logic over (tmp scratch space stays local). Again, this is to limit
|
|
271
|
+
# unnecessary bandwidth usage, PLUS, we are charged per million IO to EBS
|
|
272
|
+
#
|
|
273
|
+
# TODO:
|
|
274
|
+
# * make sure if we have a predefined ebs_vol_id, that we error out with a nice msg IF the zones do not match
|
|
275
|
+
# * can we move more of the mysql cache files back to the local disk and off of EBS, like the innodb table caches?
|
|
276
|
+
# * right now we force this task to only be run on one server; that works for db :primary => true
|
|
277
|
+
# But what is the best way to make this work if it needs to setup multiple servers (like db slaves)?
|
|
278
|
+
# I need to figure out how to do a direct mapping from a server definition to a ebs_vol_id
|
|
279
|
+
# * when we enable slaves and we setup ebs volumes on them, make it transparent to the user.
|
|
280
|
+
# have the slave create a snapshot of the db.master volume, and then use that to mount from
|
|
281
|
+
# * need to do a rollback that if the volume is created but something fails, lets uncreate it?
|
|
282
|
+
# carefull though! If it fails towards the end when information is copied over, it could cause information
|
|
283
|
+
# to be lost!
|
|
284
|
+
#
|
|
285
|
+
|
|
286
|
+
mysql_dir_root = '/var/local'
|
|
287
|
+
block_mnt = '/dev/sdh'
|
|
288
|
+
servers = find_servers_for_task(current_task)
|
|
289
|
+
|
|
290
|
+
if servers.empty?
|
|
291
|
+
raise Capistrano::NoMatchingServersError, "`#{task.fully_qualified_name}' is only run for servers matching #{task.options.inspect}, but no servers matched"
|
|
292
|
+
elsif servers.size > 1
|
|
293
|
+
raise Capistrano::Error, "`#{task.fully_qualified_name}' is can only be run on one server, not #{server.size}"
|
|
294
|
+
end
|
|
295
|
+
|
|
296
|
+
vol_id = ENV['VOLUME_ID'] || servers.first.options[:ebs_vol_id]
|
|
297
|
+
|
|
298
|
+
#HACK! capistrano doesn't allow arguments to be passed in if we call this task as a method, like 'db.enable_ebs'
|
|
299
|
+
# the places where we do call it like that, we don't want to force a move to ebs, so....
|
|
300
|
+
# if the call frame is > 1 (ie, another task called it), do NOT force the ebs move
|
|
301
|
+
no_force = task_call_frames.size > 1
|
|
302
|
+
prev_created = !(vol_id.nil? || vol_id.empty?)
|
|
303
|
+
#no vol_id was passed in, but perhaps it is already mounted...?
|
|
304
|
+
prev_created = true if !quiet_capture("mount | grep -inr '#{mysql_dir_root}' || echo ''").empty?
|
|
305
|
+
|
|
306
|
+
unless no_force && (vol_id.nil? || vol_id.empty?)
|
|
307
|
+
zone = quiet_capture("/usr/local/ec2onrails/bin/ec2_meta_data.rb -key 'placement/availability-zone'")
|
|
308
|
+
instance_id = quiet_capture("/usr/local/ec2onrails/bin/ec2_meta_data.rb -key 'instance-id'")
|
|
309
|
+
|
|
310
|
+
unless prev_created
|
|
311
|
+
puts "creating new ebs volume...."
|
|
312
|
+
size = ENV["SIZE"] || "10"
|
|
313
|
+
cmd = "ec2-create-volume -s #{size} -z #{zone} 2>&1"
|
|
314
|
+
puts "running: #{cmd}"
|
|
315
|
+
output = `#{cmd}`
|
|
316
|
+
puts output
|
|
317
|
+
vol_id = (output =~ /^VOLUME\t(.+?)\t/ && $1)
|
|
318
|
+
puts "NOTE: remember that vol_id"
|
|
319
|
+
sleep(2)
|
|
320
|
+
end
|
|
321
|
+
vol_id.strip! if vol_id
|
|
322
|
+
if quiet_capture("mount | grep -inr '#{block_mnt}' || echo ''").empty?
|
|
323
|
+
cmd = "ec2-attach-volume -d #{block_mnt} -i #{instance_id} #{vol_id} 2>&1"
|
|
324
|
+
puts "running: #{cmd}"
|
|
325
|
+
output = `#{cmd}`
|
|
326
|
+
puts output
|
|
327
|
+
if output =~ /Client.InvalidVolume.ZoneMismatch/i
|
|
328
|
+
raise Exception, "The volume you are trying to attach does not reside in the zone of your instance. Stopping!"
|
|
329
|
+
end
|
|
330
|
+
|
|
331
|
+
|
|
332
|
+
sleep(10)
|
|
333
|
+
end
|
|
334
|
+
|
|
335
|
+
ec2onrails.server.allow_sudo do
|
|
336
|
+
# try to format the volume... if it is already formatted, lets run a check on
|
|
337
|
+
# it to make sure it is ok, and then continue on
|
|
338
|
+
# if errors, the device is busy...something else is going on here and it is already mounted... skip!
|
|
339
|
+
if prev_created
|
|
340
|
+
# Stop the db (mysql server) for cases where this is being run after the original run
|
|
341
|
+
# If EBS partiion is already mounted and being used by mysql, it will fail when umount is run
|
|
342
|
+
god_status = quiet_capture("sudo god status")
|
|
343
|
+
god_status = god_status.empty? ? {} : YAML::load(god_status)
|
|
344
|
+
start_stop_db = false
|
|
345
|
+
start_stop_db = god_status['db']['mysql'] == 'up'
|
|
346
|
+
if start_stop_db
|
|
347
|
+
stop
|
|
348
|
+
puts "Waiting for mysql to stop"
|
|
349
|
+
sleep(10)
|
|
350
|
+
end
|
|
351
|
+
quiet_capture("sudo umount #{mysql_dir_root}") #unmount if need to
|
|
352
|
+
sudo "xfs_check #{block_mnt}"
|
|
353
|
+
# Restart the db if it
|
|
354
|
+
start if start_stop_db
|
|
355
|
+
else
|
|
356
|
+
sudo "mkfs.xfs #{block_mnt}"
|
|
357
|
+
end
|
|
358
|
+
|
|
359
|
+
# if not added to /etc/fstab, lets do so
|
|
360
|
+
sudo "sh -c \"grep -iqn '#{mysql_dir_root}' /etc/fstab || echo '#{block_mnt} #{mysql_dir_root} xfs noatime 0 0' >> /etc/fstab\""
|
|
361
|
+
sudo "mkdir -p #{mysql_dir_root}"
|
|
362
|
+
#if not already mounted, lets mount it
|
|
363
|
+
sudo "sh -c \"mount | grep -iqn '#{mysql_dir_root}' || mount '#{mysql_dir_root}'\""
|
|
364
|
+
|
|
365
|
+
#ok, now lets move the mysql stuff off of /mnt -> mysql_dir_root
|
|
366
|
+
stop rescue nil #already stopped
|
|
367
|
+
sudo "mkdir -p #{mysql_dir_root}/log"
|
|
368
|
+
#move the data over, but keep a symlink to the new location for backwards compatibility
|
|
369
|
+
#and do not do it if /mnt/mysql_data has already been moved
|
|
370
|
+
quiet_capture("sudo sh -c 'test ! -d #{mysql_dir_root}/mysql_data && mv /mnt/mysql_data #{mysql_dir_root}/'")
|
|
371
|
+
sudo "mv /mnt/mysql_data /mnt/mysql_data_old 2>/dev/null || echo"
|
|
372
|
+
sudo "ln -fs #{mysql_dir_root}/mysql_data /mnt/mysql_data"
|
|
373
|
+
|
|
374
|
+
#but keep the tmpdir on mnt
|
|
375
|
+
sudo "sh -c 'mkdir -p /mnt/tmp/mysql && chown mysql:mysql /mnt/tmp/mysql'"
|
|
376
|
+
#move the logs over, but keep a symlink to the new location for backwards compatibility
|
|
377
|
+
#and do not do it if the logs have already been moved
|
|
378
|
+
quiet_capture("sudo sh -c 'test ! -d #{mysql_dir_root}/log/mysql_data && mv /mnt/log/mysql #{mysql_dir_root}/log/'")
|
|
379
|
+
sudo "ln -fs #{mysql_dir_root}/log/mysql /mnt/log/mysql"
|
|
380
|
+
quiet_capture("sudo sh -c \"test -f #{mysql_dir_root}/log/mysql/mysql-bin.index && \
|
|
381
|
+
perl -pi -e 's%/mnt/log/%#{mysql_dir_root}/log/%' #{mysql_dir_root}/log/mysql/mysql-bin.index\"") rescue false
|
|
382
|
+
|
|
383
|
+
if quiet_capture("test -d /var/local/etc/mysql && echo 'yes'").empty?
|
|
384
|
+
txt = <<-FILE
|
|
385
|
+
[mysqld]
|
|
386
|
+
datadir = #{mysql_dir_root}/mysql_data
|
|
387
|
+
tmpdir = /mnt/tmp/mysql
|
|
388
|
+
log_bin = #{mysql_dir_root}/log/mysql/mysql-bin.log
|
|
389
|
+
log_slow_queries = #{mysql_dir_root}/log/mysql/mysql-slow.log
|
|
390
|
+
FILE
|
|
391
|
+
put txt, '/tmp/mysql-ec2-ebs.cnf'
|
|
392
|
+
sudo 'mv /tmp/mysql-ec2-ebs.cnf /etc/mysql/conf.d/mysql-ec2-ebs.cnf'
|
|
393
|
+
|
|
394
|
+
#keep a copy
|
|
395
|
+
sudo "rsync -aR /etc/mysql #{mysql_dir_root}/"
|
|
396
|
+
end
|
|
397
|
+
# lets use the mysql configs on the EBS volume
|
|
398
|
+
sudo "mv /etc/mysql /etc/mysql.orig 2>/dev/null"
|
|
399
|
+
sudo "ln -sf #{mysql_dir_root}/etc/mysql /etc/mysql"
|
|
400
|
+
|
|
401
|
+
#just put a README on the drive so we know what this volume is for!
|
|
402
|
+
txt = <<-FILE
|
|
403
|
+
This volume is setup to be used by Ec2onRails in conjunction with Amazon's EBS, for primary MySql database persistence.
|
|
404
|
+
RAILS_ENV: #{fetch(:rails_env, 'undefined')}
|
|
405
|
+
DOMAIN: #{fetch(:domain, 'undefined')}
|
|
406
|
+
|
|
407
|
+
Modify this volume at your own risk
|
|
408
|
+
FILE
|
|
409
|
+
|
|
410
|
+
put txt, "/tmp/VOLUME-README"
|
|
411
|
+
sudo "mv /tmp/VOLUME-README #{mysql_dir_root}/VOLUME-README"
|
|
412
|
+
#update the list of ebs volumes
|
|
413
|
+
#TODO: abstract this away into a helper method!!
|
|
414
|
+
#TODO: this first touch should *not* be needed... quiet_capture should return an empty string
|
|
415
|
+
# if the cat on a non-existant file fails (as it should). this isn't causing issues
|
|
416
|
+
# for me, but a few users have complained.... bad gemspec or something?
|
|
417
|
+
# COMMENTING OUT for now to see if the recent gemspec update improved things...
|
|
418
|
+
# ebs_info = quiet_capture("touch /etc/ec2onrails/ebs_info.yml")
|
|
419
|
+
ebs_info = quiet_capture("cat /etc/ec2onrails/ebs_info.yml")
|
|
420
|
+
ebs_info = ebs_info.empty? ? {} : YAML::load(ebs_info)
|
|
421
|
+
ebs_info[mysql_dir_root] = {'block_loc' => block_mnt, 'volume_id' => vol_id}
|
|
422
|
+
put(ebs_info.to_yaml, "/tmp/ebs_info.yml")
|
|
423
|
+
sudo "mv /tmp/ebs_info.yml /etc/ec2onrails/ebs_info.yml"
|
|
424
|
+
#lets start it back up
|
|
425
|
+
start
|
|
426
|
+
end #end of sudo
|
|
427
|
+
end
|
|
428
|
+
end
|
|
429
|
+
|
|
430
|
+
|
|
431
|
+
desc <<-DESC
|
|
432
|
+
[internal] Make sure the MySQL server has been started, just in case the db role
|
|
433
|
+
hasn't been set, e.g. when called from ec2onrails:setup.
|
|
434
|
+
(But don't enable monitoring on it.)
|
|
435
|
+
DESC
|
|
436
|
+
task :start, :roles => :db do
|
|
437
|
+
sudo "god start db"
|
|
438
|
+
# sudo "god monitor db"
|
|
439
|
+
end
|
|
440
|
+
|
|
441
|
+
task :stop, :roles => :db do
|
|
442
|
+
# sudo "god unmonitor db"
|
|
443
|
+
sudo "god stop db"
|
|
444
|
+
end
|
|
445
|
+
|
|
446
|
+
|
|
447
|
+
desc <<-DESC
|
|
448
|
+
Drop the MySQL database. Assumes there is no MySQL root \
|
|
449
|
+
password. If there is a MySQL root password, create a task that removes \
|
|
450
|
+
it and run that task before this one using a before hook.
|
|
451
|
+
DESC
|
|
452
|
+
task :drop, :roles => :db do
|
|
453
|
+
load_config
|
|
454
|
+
run %{mysql -u root -e "drop database if exists \\`#{cfg[:db_name]}\\`;"}
|
|
455
|
+
end
|
|
456
|
+
|
|
457
|
+
desc <<-DESC
|
|
458
|
+
db:drop and db:create.
|
|
459
|
+
DESC
|
|
460
|
+
task :recreate, :roles => :db do
|
|
461
|
+
drop
|
|
462
|
+
create
|
|
463
|
+
end
|
|
464
|
+
|
|
465
|
+
desc <<-DESC
|
|
466
|
+
Set a root password for MySQL, using the variable mysql_root_password \
|
|
467
|
+
if it is set. If this is done db:drop won't work.
|
|
468
|
+
DESC
|
|
469
|
+
task :set_root_password, :roles => :db do
|
|
470
|
+
if cfg[:mysql_root_password]
|
|
471
|
+
run %{mysql -u root -e "UPDATE mysql.user SET Password=PASSWORD('#{cfg[:mysql_root_password]}') WHERE User='root'; FLUSH PRIVILEGES;"}
|
|
472
|
+
end
|
|
473
|
+
end
|
|
474
|
+
|
|
475
|
+
desc <<-DESC
|
|
476
|
+
Dump the MySQL database to the S3 bucket specified by \
|
|
477
|
+
ec2onrails_config[:archive_to_bucket]. The filename will be \
|
|
478
|
+
"database-archive/<timestamp>/dump.sql.gz".
|
|
479
|
+
DESC
|
|
480
|
+
task :archive, :roles => :db do
|
|
481
|
+
run "/usr/local/ec2onrails/bin/backup_app_db.rb --bucket #{cfg[:archive_to_bucket]} --dir #{cfg[:archive_to_bucket_subdir]}"
|
|
482
|
+
end
|
|
483
|
+
|
|
484
|
+
desc <<-DESC
|
|
485
|
+
Restore the MySQL database from the S3 bucket specified by \
|
|
486
|
+
ec2onrails_config[:restore_from_bucket]. The archive filename is \
|
|
487
|
+
expected to be the default, "mysqldump.sql.gz".
|
|
488
|
+
DESC
|
|
489
|
+
task :restore, :roles => :db do
|
|
490
|
+
run "/usr/local/ec2onrails/bin/restore_app_db.rb --bucket #{cfg[:restore_from_bucket]} --dir #{cfg[:restore_from_bucket_subdir]}"
|
|
491
|
+
end
|
|
492
|
+
|
|
493
|
+
desc <<-DESC
|
|
494
|
+
[internal] Initialize the default backup folder on S3 (i.e. do a full
|
|
495
|
+
backup of the newly-created db so the automatic incremental backups
|
|
496
|
+
make sense).
|
|
497
|
+
DESC
|
|
498
|
+
task :init_backup, :roles => :db do
|
|
499
|
+
server.allow_sudo do
|
|
500
|
+
sudo "/usr/local/ec2onrails/bin/backup_app_db.rb --reset"
|
|
501
|
+
end
|
|
502
|
+
end
|
|
503
|
+
|
|
504
|
+
# do NOT run if the flag does not exist. This is placed by a startup script
|
|
505
|
+
# and it is only run on the first-startup. This means after the db has been
|
|
506
|
+
# optimized, this task will not work again.
|
|
507
|
+
#
|
|
508
|
+
# Of course you can overload it or call the file directly
|
|
509
|
+
task :optimize, :roles => :db do
|
|
510
|
+
if !quiet_capture("test -e /tmp/optimize_db_flag && echo 'file exists'").empty?
|
|
511
|
+
begin
|
|
512
|
+
sudo "/usr/local/ec2onrails/bin/optimize_mysql.rb"
|
|
513
|
+
ensure
|
|
514
|
+
sudo "rm -rf /tmp/optimize_db_flag" #remove so we cannot run again
|
|
515
|
+
end
|
|
516
|
+
else
|
|
517
|
+
puts "skipping as it looks like this task has already been run"
|
|
518
|
+
end
|
|
519
|
+
end
|
|
520
|
+
|
|
521
|
+
end
|
|
522
|
+
|
|
523
|
+
namespace :server do
|
|
524
|
+
desc <<-DESC
|
|
525
|
+
Tell the servers what roles they are in. This configures them with \
|
|
526
|
+
the appropriate settings for each role, and starts and/or stops the \
|
|
527
|
+
relevant services.
|
|
528
|
+
DESC
|
|
529
|
+
task :set_roles do
|
|
530
|
+
# TODO generate this based on the roles that actually exist so arbitrary new ones can be added
|
|
531
|
+
roles = {
|
|
532
|
+
:web => hostnames_for_role(:web),
|
|
533
|
+
:app => hostnames_for_role(:app),
|
|
534
|
+
:db_primary => hostnames_for_role(:db, :primary => true),
|
|
535
|
+
# doing th ebelow can cause errors elsewhere unless :db is populated.
|
|
536
|
+
# :db => hostnames_for_role(:db),
|
|
537
|
+
:memcache => hostnames_for_role(:memcache)
|
|
538
|
+
}
|
|
539
|
+
roles_yml = YAML::dump(roles)
|
|
540
|
+
put roles_yml, "/tmp/roles.yml"
|
|
541
|
+
server.allow_sudo do
|
|
542
|
+
sudo "cp /tmp/roles.yml /etc/ec2onrails"
|
|
543
|
+
#we want everyone to be able to read to it
|
|
544
|
+
sudo "chmod a+r /etc/ec2onrails/roles.yml"
|
|
545
|
+
sudo "/usr/local/ec2onrails/bin/set_roles.rb"
|
|
546
|
+
end
|
|
547
|
+
end
|
|
548
|
+
|
|
549
|
+
task :init_services do
|
|
550
|
+
server.allow_sudo do
|
|
551
|
+
sudo "/usr/local/ec2onrails/bin/init_services.rb"
|
|
552
|
+
end
|
|
553
|
+
end
|
|
554
|
+
|
|
555
|
+
task :setup_web_proxy, :roles => :web do
|
|
556
|
+
sudo "/usr/local/ec2onrails/bin/setup_web_proxy.rb --mode #{cfg[:web_proxy_server].to_s}"
|
|
557
|
+
end
|
|
558
|
+
|
|
559
|
+
desc <<-DESC
|
|
560
|
+
Change the default value of RAILS_ENV on the server. Technically
|
|
561
|
+
this changes the server's mongrel config to use a different value
|
|
562
|
+
for "environment". The value is specified in :rails_env.
|
|
563
|
+
Be sure to do deploy:restart after this.
|
|
564
|
+
DESC
|
|
565
|
+
task :set_rails_env do
|
|
566
|
+
rails_env = fetch(:rails_env, "production")
|
|
567
|
+
sudo "/usr/local/ec2onrails/bin/set_rails_env #{rails_env}"
|
|
568
|
+
end
|
|
569
|
+
|
|
570
|
+
desc <<-DESC
|
|
571
|
+
Upgrade to the newest versions of all Ubuntu packages.
|
|
572
|
+
DESC
|
|
573
|
+
task :upgrade_packages do
|
|
574
|
+
sudo "aptitude -q update"
|
|
575
|
+
sudo "sh -c 'export DEBIAN_FRONTEND=noninteractive; aptitude -q -y safe-upgrade'"
|
|
576
|
+
end
|
|
577
|
+
|
|
578
|
+
desc <<-DESC
|
|
579
|
+
Upgrade to the newest versions of all rubygems.
|
|
580
|
+
DESC
|
|
581
|
+
task :upgrade_gems do
|
|
582
|
+
sudo "gem update --system --no-rdoc --no-ri"
|
|
583
|
+
sudo "gem update --no-rdoc --no-ri" do |ch, str, data|
|
|
584
|
+
ch[:data] ||= ""
|
|
585
|
+
ch[:data] << data
|
|
586
|
+
if data =~ />\s*$/
|
|
587
|
+
puts data
|
|
588
|
+
choice = Capistrano::CLI.ui.ask("The gem command is asking for a number:")
|
|
589
|
+
ch.send_data("#{choice}\n")
|
|
590
|
+
else
|
|
591
|
+
puts data
|
|
592
|
+
end
|
|
593
|
+
end
|
|
594
|
+
end
|
|
595
|
+
|
|
596
|
+
desc <<-DESC
|
|
597
|
+
Install extra Ubuntu packages. Set ec2onrails_config[:packages], it \
|
|
598
|
+
should be an array of strings.
|
|
599
|
+
NOTE: the package installation will be non-interactive, if the packages \
|
|
600
|
+
require configuration either set ec2onrails_config[:interactive_packages] \
|
|
601
|
+
like you would for ec2onrails_config[:packages] (we'll flood the server \
|
|
602
|
+
with 'Y' inputs), or log in as 'root' and run \
|
|
603
|
+
'dpkg-reconfigure packagename' or replace the package's config files \
|
|
604
|
+
using the 'ec2onrails:server:deploy_files' task.
|
|
605
|
+
DESC
|
|
606
|
+
task :install_packages do
|
|
607
|
+
sudo "aptitude -q update"
|
|
608
|
+
if cfg[:packages] && cfg[:packages].any?
|
|
609
|
+
sudo "sh -c 'export DEBIAN_FRONTEND=noninteractive; aptitude -q -y install #{cfg[:packages].join(' ')}'"
|
|
610
|
+
end
|
|
611
|
+
if cfg[:interactive_packages] && cfg[:interactive_packages].any?
|
|
612
|
+
# sudo "aptitude install #{cfg[:interactive_packages].join(' ')}", {:env => {'DEBIAN_FRONTEND' => 'readline'} }
|
|
613
|
+
#trying to pick WHEN to send a Y is a bit tricky...it totally depends on the
|
|
614
|
+
#interactive package you want to install. FLOODING it with 'Y'... but not sure how
|
|
615
|
+
#'correct' or robust this is
|
|
616
|
+
cmd = "sudo sh -c 'export DEBIAN_FRONTEND=readline; aptitude -y -q install #{cfg[:interactive_packages].join(' ')}'"
|
|
617
|
+
run(cmd) do |channel, stream, data|
|
|
618
|
+
channel.send_data "Y\n"
|
|
619
|
+
end
|
|
620
|
+
end
|
|
621
|
+
end
|
|
622
|
+
|
|
623
|
+
desc <<-DESC
|
|
624
|
+
Provide extra security measures. Set ec2onrails_config[:harden_server] = true \
|
|
625
|
+
to allow the hardening of the server.
|
|
626
|
+
These security measures are those which can make initial setup and playing around
|
|
627
|
+
with Ec2onRails tricky. For example, you can be logged out of your server forever
|
|
628
|
+
DESC
|
|
629
|
+
task :harden_server do
|
|
630
|
+
#NOTES: for those security features that will get in the way of ease-of-use
|
|
631
|
+
# hook them in here
|
|
632
|
+
if cfg[:harden_server]
|
|
633
|
+
#lets install some extra packages:
|
|
634
|
+
# denyhosts: sshd security tool. config file is already installed...
|
|
635
|
+
#
|
|
636
|
+
security_pkgs = %w{denyhosts}
|
|
637
|
+
sudo "sh -c 'export DEBIAN_FRONTEND=noninteractive; aptitude -q -y install #{security_pkgs.join(' ')}'"
|
|
638
|
+
end
|
|
639
|
+
end
|
|
640
|
+
|
|
641
|
+
desc <<-DESC
|
|
642
|
+
Install extra rubygems. Set ec2onrails_config[:rubygems], it should \
|
|
643
|
+
be with an array of strings.
|
|
644
|
+
DESC
|
|
645
|
+
task :install_gems do
|
|
646
|
+
if cfg[:rubygems]
|
|
647
|
+
cfg[:rubygems].each do |gem|
|
|
648
|
+
sudo "gem install #{gem} --no-rdoc --no-ri" do |ch, str, data|
|
|
649
|
+
ch[:data] ||= ""
|
|
650
|
+
ch[:data] << data
|
|
651
|
+
if data =~ />\s*$/
|
|
652
|
+
puts data
|
|
653
|
+
choice = Capistrano::CLI.ui.ask("The gem command is asking for a number:")
|
|
654
|
+
ch.send_data("#{choice}\n")
|
|
655
|
+
else
|
|
656
|
+
puts data
|
|
657
|
+
end
|
|
658
|
+
end
|
|
659
|
+
end
|
|
660
|
+
end
|
|
661
|
+
end
|
|
662
|
+
|
|
663
|
+
task :run_rails_rake_gems_install do
|
|
664
|
+
#if running under Rails 2.1, lets trigger 'rake gems:install', but in such a way
|
|
665
|
+
#so it fails gracefully if running rails < 2.1
|
|
666
|
+
# ALSO, this might be the first time rake is run, and running it as sudo means that
|
|
667
|
+
# if any plugins are loaded and create directories... like what image_science does for
|
|
668
|
+
# ruby_inline, then the dirs will be created as root. so trigger the rails loading
|
|
669
|
+
# very quickly before the sudo is called
|
|
670
|
+
# run "cd #{release_path} && rake RAILS_ENV=#{rails_env} -T 1>/dev/null && sudo rake RAILS_ENV=#{rails_env} gems:install"
|
|
671
|
+
ec2onrails.server.allow_sudo do
|
|
672
|
+
output = quiet_capture "cd #{release_path} && rake RAILS_ENV=#{rails_env} db:version 2>&1 1>/dev/null || sudo rake RAILS_ENV=#{rails_env} gems:install"
|
|
673
|
+
puts output
|
|
674
|
+
end
|
|
675
|
+
end
|
|
676
|
+
|
|
677
|
+
desc <<-DESC
|
|
678
|
+
Add extra gem sources to rubygems (to able to fetch gems from for example gems.github.com).
|
|
679
|
+
Set ec2onrails_config[:rubygems_sources], it should be with an array of strings.
|
|
680
|
+
DESC
|
|
681
|
+
task :add_gem_sources do
|
|
682
|
+
if cfg[:rubygems_sources]
|
|
683
|
+
cfg[:rubygems_sources].each do |gem_source|
|
|
684
|
+
sudo "gem sources -a #{gem_source}"
|
|
685
|
+
end
|
|
686
|
+
end
|
|
687
|
+
end
|
|
688
|
+
|
|
689
|
+
desc <<-DESC
|
|
690
|
+
A convenience task to upgrade existing packages and gems and install \
|
|
691
|
+
specified new ones.
|
|
692
|
+
DESC
|
|
693
|
+
task :upgrade_and_install_all do
|
|
694
|
+
upgrade_packages
|
|
695
|
+
upgrade_gems
|
|
696
|
+
install_packages
|
|
697
|
+
install_gems
|
|
698
|
+
end
|
|
699
|
+
|
|
700
|
+
desc <<-DESC
|
|
701
|
+
Set the timezone using the value of the variable named timezone. \
|
|
702
|
+
Valid options for timezone can be determined by the contents of \
|
|
703
|
+
/usr/share/zoneinfo, which can be seen here: \
|
|
704
|
+
http://packages.ubuntu.com/cgi-bin/search_contents.pl?searchmode=filelist&word=tzdata&version=gutsy&arch=all&page=1&number=all \
|
|
705
|
+
Remove 'usr/share/zoneinfo/' from the filename, and use the last \
|
|
706
|
+
directory and file as the value. For example 'Africa/Abidjan' or \
|
|
707
|
+
'posix/GMT' or 'Canada/Eastern'.
|
|
708
|
+
DESC
|
|
709
|
+
task :set_timezone do
|
|
710
|
+
if cfg[:timezone]
|
|
711
|
+
ec2onrails.server.allow_sudo do
|
|
712
|
+
sudo "bash -c 'echo #{cfg[:timezone]} > /etc/timezone'"
|
|
713
|
+
sudo "cp /usr/share/zoneinfo/#{cfg[:timezone]} /etc/localtime"
|
|
714
|
+
end
|
|
715
|
+
end
|
|
716
|
+
end
|
|
717
|
+
|
|
718
|
+
desc <<-DESC
|
|
719
|
+
Deploy a set of config files to the server, the files will be owned by \
|
|
720
|
+
root. This doesn't delete any files from the server. This is intended
|
|
721
|
+
mainly for customized config files for new packages installed via the \
|
|
722
|
+
ec2onrails:server:install_packages task. Subdirectories and files \
|
|
723
|
+
inside here will be placed within the same directory structure \
|
|
724
|
+
relative to the root of the server's filesystem.
|
|
725
|
+
DESC
|
|
726
|
+
task :deploy_files do
|
|
727
|
+
if cfg[:server_config_files_root]
|
|
728
|
+
begin
|
|
729
|
+
filename = "config_files.tar"
|
|
730
|
+
local_file = "#{Dir.tmpdir}/#{filename}"
|
|
731
|
+
remote_file = "/tmp/#{filename}"
|
|
732
|
+
FileUtils.cd(cfg[:server_config_files_root]) do
|
|
733
|
+
File.open(local_file, 'wb') { |tar| Minitar.pack(".", tar) }
|
|
734
|
+
end
|
|
735
|
+
put File.read(local_file), remote_file
|
|
736
|
+
sudo "tar xvf #{remote_file} -o -C /"
|
|
737
|
+
ensure
|
|
738
|
+
rm_rf local_file
|
|
739
|
+
sudo "rm -f #{remote_file}"
|
|
740
|
+
end
|
|
741
|
+
end
|
|
742
|
+
end
|
|
743
|
+
|
|
744
|
+
desc <<-DESC
|
|
745
|
+
Restart a set of services. Set ec2onrails_config[:services_to_restart] \
|
|
746
|
+
to an array of strings. It's assumed that each service has a script \
|
|
747
|
+
in /etc/init.d
|
|
748
|
+
DESC
|
|
749
|
+
task :restart_services do
|
|
750
|
+
if cfg[:services_to_restart] && cfg[:services_to_restart].any?
|
|
751
|
+
cfg[:services_to_restart].each do |service|
|
|
752
|
+
run_init_script(service, "restart")
|
|
753
|
+
end
|
|
754
|
+
end
|
|
755
|
+
end
|
|
756
|
+
|
|
757
|
+
desc <<-DESC
|
|
758
|
+
Set the email address that mail to the app user forwards to.
|
|
759
|
+
DESC
|
|
760
|
+
task :set_mail_forward_address do
|
|
761
|
+
run "echo '#{cfg[:mail_forward_address]}' >> /home/app/.forward" if cfg[:mail_forward_address]
|
|
762
|
+
# put cfg[:admin_mail_forward_address], "/home/admin/.forward" if cfg[:admin_mail_forward_address]
|
|
763
|
+
end
|
|
764
|
+
|
|
765
|
+
desc <<-DESC
|
|
766
|
+
Enable ssl for the web server. The SSL cert file should be in
|
|
767
|
+
/etc/ssl/certs/default.pem and the SSL key file should be in
|
|
768
|
+
/etc/ssl/private/default.key (use the deploy_files task).
|
|
769
|
+
DESC
|
|
770
|
+
task :enable_ssl, :roles => :web do
|
|
771
|
+
#TODO: enable for nginx
|
|
772
|
+
sudo "a2enmod ssl"
|
|
773
|
+
sudo "a2enmod headers" # the headers module is necessary to forward a header so that rails can detect it is handling an SSL connection. NPG 7/11/08
|
|
774
|
+
sudo "a2ensite default-ssl"
|
|
775
|
+
run_init_script("web_proxy", "restart")
|
|
776
|
+
end
|
|
777
|
+
|
|
778
|
+
desc <<-DESC
|
|
779
|
+
Restrict the main user's sudo access.
|
|
780
|
+
Defaults the user to only be able to \
|
|
781
|
+
sudo to god
|
|
782
|
+
DESC
|
|
783
|
+
task :restrict_sudo_access do
|
|
784
|
+
old_user = fetch(:user)
|
|
785
|
+
begin
|
|
786
|
+
set :user, 'root'
|
|
787
|
+
sessions.clear #clear out sessions cache..... this way the ssh connections are reinitialized
|
|
788
|
+
sudo "cp -f /etc/sudoers.restricted_access /etc/sudoers"
|
|
789
|
+
# run "ln -sf /etc/sudoers.restricted_access /etc/sudoers"
|
|
790
|
+
ensure
|
|
791
|
+
set :user, old_user
|
|
792
|
+
sessions.clear
|
|
793
|
+
end
|
|
794
|
+
end
|
|
795
|
+
|
|
796
|
+
desc <<-DESC
|
|
797
|
+
Grant *FULL* sudo access to the main user.
|
|
798
|
+
DESC
|
|
799
|
+
task :grant_sudo_access do
|
|
800
|
+
allow_sudo
|
|
801
|
+
end
|
|
802
|
+
|
|
803
|
+
@within_sudo = 0
|
|
804
|
+
def allow_sudo
|
|
805
|
+
begin
|
|
806
|
+
@within_sudo += 1
|
|
807
|
+
old_user = fetch(:user)
|
|
808
|
+
if @within_sudo > 1
|
|
809
|
+
yield if block_given?
|
|
810
|
+
true
|
|
811
|
+
elsif capture("ls -l /etc/sudoers /etc/sudoers.full_access | awk '{print $5}'").split.uniq.size == 1
|
|
812
|
+
yield if block_given?
|
|
813
|
+
false
|
|
814
|
+
else
|
|
815
|
+
begin
|
|
816
|
+
# need to cheet and temporarily set the user to ROOT so we
|
|
817
|
+
# can (re)grant full sudo access.
|
|
818
|
+
# we can do this because the root and app user have the same
|
|
819
|
+
# ssh login preferences....
|
|
820
|
+
#
|
|
821
|
+
# TODO:
|
|
822
|
+
# do not escalate priv. to root...use another user like 'admin' that has full sudo access
|
|
823
|
+
set :user, 'root'
|
|
824
|
+
sessions.clear #clear out sessions cache..... this way the ssh connections are reinitialized
|
|
825
|
+
run "cp -f /etc/sudoers.full_access /etc/sudoers"
|
|
826
|
+
set :user, old_user
|
|
827
|
+
sessions.clear
|
|
828
|
+
yield if block_given?
|
|
829
|
+
ensure
|
|
830
|
+
server.restrict_sudo_access if block_given?
|
|
831
|
+
set :user, old_user
|
|
832
|
+
sessions.clear
|
|
833
|
+
true
|
|
834
|
+
end
|
|
835
|
+
end
|
|
836
|
+
ensure
|
|
837
|
+
@within_sudo -= 1
|
|
838
|
+
end
|
|
839
|
+
end
|
|
840
|
+
end
|
|
841
|
+
|
|
842
|
+
end
|
|
843
|
+
end
|
|
844
|
+
|