Empact-ec2onrails 0.9.9
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +159 -0
- data/LICENSE +339 -0
- data/README.rdoc +232 -0
- data/Rakefile +34 -0
- data/examples/Capfile +3 -0
- data/examples/deploy.rb +85 -0
- data/examples/s3.yml +9 -0
- data/lib/ec2onrails.rb +20 -0
- data/lib/ec2onrails/capistrano_utils.rb +33 -0
- data/lib/ec2onrails/recipes.rb +460 -0
- data/lib/ec2onrails/version.rb +31 -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 +36 -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 +156 -0
data/README.rdoc
ADDED
@@ -0,0 +1,232 @@
|
|
1
|
+
= EC2 on Rails
|
2
|
+
|
3
|
+
|
4
|
+
== Deploy a Ruby on Rails app on EC2 in five minutes
|
5
|
+
|
6
|
+
EC2 on Rails is an Ubuntu Linux server image for
|
7
|
+
"Amazon's EC2 hosting service":http://www.amazon.com/b/ref=sc_fe_l_2/102-6342260-7987311?ie=UTF8&node=201590011&no=3435361
|
8
|
+
that's ready to run a standard Ruby on Rails application with little or no customization.
|
9
|
+
It's a Ruby on Rails "virtual appliance":http://en.wikipedia.org/wiki/Virtual_appliance.
|
10
|
+
|
11
|
+
If you have an EC2 account and can start EC2 instances you're five minutes away from deploying
|
12
|
+
your Rails app.
|
13
|
+
|
14
|
+
EC2 on Rails is "opinionated software":http://gettingreal.37signals.com/ch04_Make_Opinionated_Software.php:
|
15
|
+
the opinion is that for many rails apps the server setup can be generalized
|
16
|
+
and shared the same way as the web application framework itself. For many people (Twitter, this isn't for you)
|
17
|
+
the server image can be treated the same way as other shared libraries. And if the day comes when your needs are
|
18
|
+
unique enough that EC2 on Rails can't be configured to work for you then you can bundle your own image from it
|
19
|
+
or fork the build source and customize it.
|
20
|
+
|
21
|
+
But until then, why spend your time configuring servers?
|
22
|
+
|
23
|
+
Features of the EC2 image:
|
24
|
+
|
25
|
+
* Ready to deploy a Rails app with little or no configuration of the server required
|
26
|
+
* Automatic backup of MySQL database to S3 (full backup nightly + incremental backup using binary logs every 5 minutes)
|
27
|
+
* Capistrano tasks to customize the server image, archive and restore the database to/from S3, and more (available as a rubygem)
|
28
|
+
* Mongrel_cluster behind Apache 2.2, configured according to
|
29
|
+
"Coda Hale's excellent guide":http://blog.codahale.com/2006/06/19/time-for-a-grown-up-server-rails-mongrel-apache-capistrano-and-you/
|
30
|
+
* Ruby on Rails 2.1.0, 2.0.2 and 1.2.6
|
31
|
+
* Ruby 1.8.6
|
32
|
+
* MySQL 5
|
33
|
+
* "memcached":http://www.danga.com/memcached/
|
34
|
+
* "monit":http://www.tildeslash.com/monit/ configured to monitor apache, mongrel, mysql, memcached, drive space and system load
|
35
|
+
* Ubuntu 8.04 LTS "Hardy" base image built using "Eric Hammond's EC2 Ubuntu script":http://alestic.com/
|
36
|
+
* SSL support
|
37
|
+
* Amazon AMI tools installed
|
38
|
+
* MySQL, Apache, and syslog configured to use /mnt for data and logging so you don't fill up EC2's small root filesystem
|
39
|
+
* Automatically archives Rails and Apache logs to S3 nightly.
|
40
|
+
* 32-bit and 64-bit images available (supports all instance types, small to extra large).
|
41
|
+
* Created using a build file, full source is "available":http://rubyforge.org/scm/?group_id=4552 (the EC2 on Rails script is run from "Eric Hammond's EC2 Ubuntu script":http://alestic.com/)
|
42
|
+
* Can be used as a clustered Rails app running on multiple instances
|
43
|
+
* Automatically runs hourly, daily, weekly and monthly scripts if they exist in Rails application's script directory
|
44
|
+
* Local "Postfix":http://www.postfix.org/ SMTP mail server (only available from within the instance, not listening on external network interfaces)
|
45
|
+
|
46
|
+
|
47
|
+
== Using the image
|
48
|
+
|
49
|
+
This documentation will be improved soon, for now hopefully this covers the basics.
|
50
|
+
|
51
|
+
The current AMI id's are:
|
52
|
+
* ami-c9bc58a0 (32-bit)
|
53
|
+
* ami-cbbc58a2 (64-bit)
|
54
|
+
|
55
|
+
_I will keep these images for as long as possible, they will not be deleted for at least a few years._
|
56
|
+
|
57
|
+
|
58
|
+
=== 1. Install the gem
|
59
|
+
|
60
|
+
<pre>sudo gem install ec2onrails</pre>
|
61
|
+
|
62
|
+
=== 2. Add the config files to your Rails app
|
63
|
+
|
64
|
+
Put "Capfile":http://ec2onrails.rubyforge.org/svn/trunk/documentation/examples/Capfile
|
65
|
+
in the root of your rails folder, and put
|
66
|
+
"deploy.rb":http://ec2onrails.rubyforge.org/svn/trunk/documentation/examples/deploy.rb
|
67
|
+
and
|
68
|
+
"s3.yml":http://ec2onrails.rubyforge.org/svn/trunk/documentation/examples/s3.yml
|
69
|
+
in the config folder.
|
70
|
+
|
71
|
+
_Be sure to customize those files and read the comments._
|
72
|
+
|
73
|
+
Also, use the hostname "db_primary" in your database.yml file. After running "cap ec2onrails:server:set_roles" it will resolve
|
74
|
+
to the instance defined in your Capistrano "db" role.
|
75
|
+
|
76
|
+
=== 4. Start up one or more instances of the image.
|
77
|
+
|
78
|
+
There is nothing EC2 on Rails-specific here yet (though soon there will be a Capistrano task to do this for you),
|
79
|
+
if you've started EC2 instances before you can skip this section. Otherwise, I'm not going to lie, this part is complicated
|
80
|
+
and will take a lot more than 5 minutes the first time.
|
81
|
+
|
82
|
+
Read the
|
83
|
+
"running an instance section":http://docs.amazonwebservices.com/AWSEC2/2007-08-29/GettingStartedGuide/running-an-instance.html
|
84
|
+
in Amazon's getting started guide.
|
85
|
+
|
86
|
+
For the AMI id's of the current images do <code>cap ec2onrails:ami_ids</code> from within the app that you
|
87
|
+
configured in the previous step (they're also listed earlier on this page).
|
88
|
+
|
89
|
+
_NOTE: Only use the images that match the current version of the gem._
|
90
|
+
|
91
|
+
Please see the "change log":http://ec2onrails.rubyforge.org/svn/trunk/gem/History.txt for release notes, and
|
92
|
+
see the "list of open issues":http://rubyforge.org/tracker/?atid=17558&group_id=4552&func=browse.
|
93
|
+
|
94
|
+
As is "standard for public AMI's":http://docs.amazonwebservices.com/AWSEC2/2007-08-29/DeveloperGuide/public-ami-guidelines.html,
|
95
|
+
password-based logins are disabled. You log in with your own
|
96
|
+
"public/private keypair":http://docs.amazonwebservices.com/AWSEC2/2007-08-29/GettingStartedGuide/running-an-instance.html.
|
97
|
+
|
98
|
+
Most basic things can be configured automatically by the Capistrano tasks, but if you want to
|
99
|
+
you can login by ssh as a user named "admin" (has sudo ability) or as "app" (the user
|
100
|
+
that the app runs as, does not have sudo ability). The Capistrano tasks automatically
|
101
|
+
use the app user to deploy the app, and the admin user for server admin tasks
|
102
|
+
that require sudo.
|
103
|
+
|
104
|
+
IMPORTANT: Double-check "your firewall settings":http://docs.amazonwebservices.com/AWSEC2/2007-08-29/GettingStartedGuide/running-an-instance.html.
|
105
|
+
Be sure that you haven't allowed public access to any ports other than TCP 22 and TCP 80
|
106
|
+
(and possibly TCP 443 if you're going to enable HTTPS).
|
107
|
+
If you're using multiple instances, be sure to allow them network access to each other.
|
108
|
+
|
109
|
+
|
110
|
+
=== 5. Copy your public key from the server to keep Capistrano happy
|
111
|
+
|
112
|
+
This is a workaround for a quirk in Capistrano. Technically all you should need to connect to the server is the private
|
113
|
+
key file, the public key is on the server. But for some reason
|
114
|
+
"Capistrano requires that you have both the public key and the private key files together on the client":http://groups.google.com/group/capistrano/browse_thread/thread/1102208ff925d18.
|
115
|
+
|
116
|
+
There is a Capistrano task that tries to fix this for you. From within the root of your rails app do:
|
117
|
+
|
118
|
+
<pre>cap ec2onrails:get_public_key_from_server</pre>
|
119
|
+
|
120
|
+
Note, this will only work if you have an external ssh command in the path, it won't work for most Windows users.
|
121
|
+
|
122
|
+
|
123
|
+
=== 6. Deploy the app with Capistrano
|
124
|
+
|
125
|
+
Now that the gem is installed, your deploy.rb is configured and you can start and stop EC2 instances,
|
126
|
+
this is the only thing you'll need to do from now on.
|
127
|
+
|
128
|
+
<pre>
|
129
|
+
cap ec2onrails:setup
|
130
|
+
cap deploy:cold
|
131
|
+
</pre>
|
132
|
+
|
133
|
+
Yes, it's that easy! The setup task will set the server's timezone, install any
|
134
|
+
gems and Ubuntu packages that you specified in the config file, and
|
135
|
+
create your database.
|
136
|
+
|
137
|
+
That's it, your app is now running on EC2!!
|
138
|
+
|
139
|
+
|
140
|
+
== Capistrano tasks
|
141
|
+
|
142
|
+
"Capistrano":http://capify.org is the most commonly used Rails deployment tool. It comes with many standard "tasks",
|
143
|
+
and the EC2 on Rails gem includes Capistrano tasks specifically for configuring the server instance.
|
144
|
+
|
145
|
+
Capistrano is run from the command-line using the "cap" command, with a task name given as an argument.
|
146
|
+
|
147
|
+
=== Commonly-used tasks
|
148
|
+
|
149
|
+
You'll mostly need just the following Capistrano tasks:
|
150
|
+
|
151
|
+
* <code>cap ec2onrails:ami_ids</code>
|
152
|
+
Shows the AMI id's of the images that match the current version of the gem.
|
153
|
+
|
154
|
+
* <code>cap ec2onrails:setup</code>
|
155
|
+
This task configures a newly-launched instance. This is the first thing you should do after
|
156
|
+
starting a new instance. It can be run more than once without ill effect. After running
|
157
|
+
"cap ec2onrails:setup" the next thing to do is run "cap deploy:cold"
|
158
|
+
|
159
|
+
* <code>cap ec2onrails:server:set_roles</code>
|
160
|
+
Customizes each instance for it's role(s) (as defined in your Capistrano deploy.rb file).
|
161
|
+
Run this after starting or stopping instances.
|
162
|
+
For now this just makes sure that only the appropriate services (Apache, Mongrel, and/or MySQL)
|
163
|
+
are running. Eventually this will customize settings for the running services also. Note that
|
164
|
+
an instance can have more than one role. If there's only one instance it will have all roles.
|
165
|
+
|
166
|
+
Note that due to the way that Capistrano works all tasks are run
|
167
|
+
against all hosts that are currently defined in the deploy.rb file.
|
168
|
+
So if you start a new instance then add it to your deploy.rb you will need to run
|
169
|
+
"cap ec2onrails:setup" again which will be run on all existing instances.
|
170
|
+
|
171
|
+
|
172
|
+
=== Database management tasks
|
173
|
+
|
174
|
+
* <code>cap ec2onrails:db:archive</code>
|
175
|
+
Archive the MySQL database to the bucket specified in your deploy.rb. This is for archiving a snapshot of your
|
176
|
+
database into any S3 bucket. For example, you might want to do this before deploying.
|
177
|
+
|
178
|
+
* <code>cap ec2onrails:db:restore</code>
|
179
|
+
Restore the MySQL database from the bucket specified in your deploy.rb
|
180
|
+
For example, I use this to restore the current production data (from my actual production backup
|
181
|
+
bucket) onto a staging server that has the current production version of my
|
182
|
+
app. I then deploy the new version which tests migrations exactly as they'll
|
183
|
+
run on the production server.
|
184
|
+
|
185
|
+
To get a full list of the Capistrano tasks at any time type <code>cap -T</code> from with your rails app root.
|
186
|
+
|
187
|
+
== Building the image
|
188
|
+
|
189
|
+
Building the image is not required, most people will simply use the prebuilt public
|
190
|
+
image, but there is also a build script that builds the image. It's meant to be called by
|
191
|
+
"Eric Hammond's EC2 Ubuntu script":http://alestic.com/.
|
192
|
+
|
193
|
+
|
194
|
+
== Mailing lists
|
195
|
+
|
196
|
+
There are two Google groups, one for
|
197
|
+
"announcements":http://groups.google.com/group/ec2-on-rails-announce
|
198
|
+
(usually just new release announcements) and one for
|
199
|
+
"discussion":http://groups.google.com/group/ec2-on-rails-discuss.
|
200
|
+
|
201
|
+
|
202
|
+
== Comments
|
203
|
+
|
204
|
+
Comments are welcome. Send an email to "Paul Dowman":http://pauldowman.com/contact/
|
205
|
+
or to the "Google group":http://groups.google.com/group/ec2-on-rails-discuss.
|
206
|
+
If you find bugs please file them
|
207
|
+
"here":http://rubyforge.org/tracker/?atid=17558&group_id=4552&func=browse
|
208
|
+
or send me an "email":http://pauldowman.com/contact/.
|
209
|
+
|
210
|
+
|
211
|
+
== Change log
|
212
|
+
|
213
|
+
See the "change log":http://ec2onrails.rubyforge.org/svn/trunk/gem/History.txt.
|
214
|
+
|
215
|
+
|
216
|
+
== How to submit patches
|
217
|
+
|
218
|
+
Pleae read the "8 steps for fixing other people's code":http://drnicwilliams.com/2007/06/01/8-steps-for-fixing-other-peoples-code/.
|
219
|
+
The source code can be checked out anonymously using:
|
220
|
+
<pre>
|
221
|
+
svn checkout http://ec2onrails.rubyforge.org/svn/trunk ec2onrails
|
222
|
+
</pre>
|
223
|
+
|
224
|
+
Patches can be submitted to the "RubyForge Tracker":http://rubyforge.org/tracker/?atid=17560&group_id=4552&func=browse
|
225
|
+
or "emailed directly to me":http://pauldowman.com/contact/ .
|
226
|
+
|
227
|
+
== License
|
228
|
+
|
229
|
+
This code is free to use under the terms of the GPL v2.
|
230
|
+
|
231
|
+
If you find EC2 on Rails useful please "recommend Paul Dowman":http://www.workingwithrails.com/person/10131-paul-dowman
|
232
|
+
at Working With Rails.
|
data/Rakefile
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake/gempackagetask'
|
3
|
+
require 'rake/testtask'
|
4
|
+
require 'rake/rdoctask'
|
5
|
+
require 'spec/rake/spectask'
|
6
|
+
|
7
|
+
# read the contents of the gemspec, eval it, and assign it to 'spec'
|
8
|
+
# this lets us maintain all gemspec info in one place. Nice and DRY.
|
9
|
+
spec = eval(IO.read("ec2onrails.gemspec"))
|
10
|
+
|
11
|
+
Rake::GemPackageTask.new(spec) do |pkg|
|
12
|
+
pkg.gem_spec = spec
|
13
|
+
end
|
14
|
+
|
15
|
+
task :install => [:package] do
|
16
|
+
sh %{sudo gem install pkg/#{GEM}-#{VERSION}}
|
17
|
+
end
|
18
|
+
|
19
|
+
Rake::TestTask.new do |t|
|
20
|
+
t.libs << "test"
|
21
|
+
t.test_files = FileList['test/test*.rb']
|
22
|
+
t.verbose = true
|
23
|
+
end
|
24
|
+
|
25
|
+
Spec::Rake::SpecTask.new('spec') do |t|
|
26
|
+
t.spec_files = FileList['test/spec/lib/*.rb']
|
27
|
+
end
|
28
|
+
|
29
|
+
Rake::RDocTask.new do |rd|
|
30
|
+
rd.main = "README.rdoc"
|
31
|
+
rd.rdoc_files.include("README.rdoc", "lib/**/*.rb")
|
32
|
+
rd.rdoc_dir = 'doc'
|
33
|
+
rd.options = spec.rdoc_options
|
34
|
+
end
|
data/examples/Capfile
ADDED
data/examples/deploy.rb
ADDED
@@ -0,0 +1,85 @@
|
|
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 :db, "ec2-56-xx-xx-xx.z-1.compute-1.amazonaws.com", :primary => true
|
19
|
+
role :memcache, "ec2-12-xx-xx-xx.z-1.compute-1.amazonaws.com"
|
20
|
+
|
21
|
+
# Whatever you set here will be taken set as the default RAILS_ENV value
|
22
|
+
# on the server. Your app and your hourly/daily/weekly/monthly scripts
|
23
|
+
# will run with RAILS_ENV set to this value.
|
24
|
+
set :rails_env, "production"
|
25
|
+
|
26
|
+
# EC2 on Rails config.
|
27
|
+
# NOTE: Some of these should be omitted if not needed.
|
28
|
+
set :ec2onrails_config, {
|
29
|
+
# S3 bucket and "subdir" used by the ec2onrails:db:restore task
|
30
|
+
:restore_from_bucket => "your-bucket",
|
31
|
+
:restore_from_bucket_subdir => "database",
|
32
|
+
|
33
|
+
# S3 bucket and "subdir" used by the ec2onrails:db:archive task
|
34
|
+
# This does not affect the automatic backup of your MySQL db to S3, it's
|
35
|
+
# just for manually archiving a db snapshot to a different bucket if
|
36
|
+
# desired.
|
37
|
+
:archive_to_bucket => "your-other-bucket",
|
38
|
+
:archive_to_bucket_subdir => "db-archive/#{Time.new.strftime('%Y-%m-%d--%H-%M-%S')}",
|
39
|
+
|
40
|
+
# Set a root password for MySQL. Run "cap ec2onrails:db:set_root_password"
|
41
|
+
# to enable this. This is optional, and after doing this the
|
42
|
+
# ec2onrails:db:drop task won't work, but be aware that MySQL accepts
|
43
|
+
# connections on the public network interface (you should block the MySQL
|
44
|
+
# port with the firewall anyway).
|
45
|
+
# If you don't care about setting the mysql root password then remove this.
|
46
|
+
:mysql_root_password => "your-mysql-root-password",
|
47
|
+
|
48
|
+
# Any extra Ubuntu packages to install if desired
|
49
|
+
# If you don't want to install extra packages then remove this.
|
50
|
+
:packages => ["logwatch", "imagemagick"],
|
51
|
+
|
52
|
+
# Any extra RubyGems to install if desired: can be "gemname" or if a
|
53
|
+
# particular version is desired "gemname -v 1.0.1"
|
54
|
+
# If you don't want to install extra rubygems then remove this
|
55
|
+
:rubygems => ["rmagick", "rfacebook -v 0.9.7"],
|
56
|
+
|
57
|
+
# Set the server timezone. run "cap -e ec2onrails:server:set_timezone" for
|
58
|
+
# details
|
59
|
+
:timezone => "Canada/Eastern",
|
60
|
+
|
61
|
+
# Files to deploy to the server (they'll be owned by root). It's intended
|
62
|
+
# mainly for customized config files for new packages installed via the
|
63
|
+
# ec2onrails:server:install_packages task. Subdirectories and files inside
|
64
|
+
# here will be placed in the same structure relative to the root of the
|
65
|
+
# server's filesystem.
|
66
|
+
# If you don't need to deploy customized config files to the server then
|
67
|
+
# remove this.
|
68
|
+
:server_config_files_root => "../server_config",
|
69
|
+
|
70
|
+
# If config files are deployed, some services might need to be restarted.
|
71
|
+
# If you don't need to deploy customized config files to the server then
|
72
|
+
# remove this.
|
73
|
+
:services_to_restart => %w(apache2 postfix sysklogd),
|
74
|
+
|
75
|
+
# Set an email address to forward admin mail messages to. If you don't
|
76
|
+
# want to receive mail from the server (e.g. monit alert messages) then
|
77
|
+
# remove this.
|
78
|
+
:admin_mail_forward_address => "you@yourdomain.com",
|
79
|
+
|
80
|
+
# Set this if you want SSL to be enabled on the web server. The SSL cert
|
81
|
+
# and key files need to exist on the server, The cert file should be in
|
82
|
+
# /etc/ssl/certs/default.pem and the key file should be in
|
83
|
+
# /etc/ssl/private/default.key (see :server_config_files_root).
|
84
|
+
:enable_ssl => true
|
85
|
+
}
|
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,33 @@
|
|
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
|
+
def make_admin_role_for(role)
|
14
|
+
newrole = "#{role.to_s}_admin".to_sym
|
15
|
+
roles[role].each do |srv_def|
|
16
|
+
options = srv_def.options.dup
|
17
|
+
options[:user] = "admin"
|
18
|
+
options[:port] = srv_def.port
|
19
|
+
options[:no_release] = true
|
20
|
+
role newrole, srv_def.host, options
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# return hostnames for the role named role_sym that has the specified options
|
25
|
+
def hostnames_for_role(role_sym, options = {})
|
26
|
+
role = roles[role_sym]
|
27
|
+
unless role
|
28
|
+
return []
|
29
|
+
end
|
30
|
+
role.select{|s| s.options == options}.collect{|s| s.host}
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,460 @@
|
|
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
|
+
set :ec2onrails_version, Ec2onrails::VERSION::STRING
|
40
|
+
set :image_id_32_bit, Ec2onrails::VERSION::AMI_ID_32_BIT
|
41
|
+
set :image_id_64_bit, Ec2onrails::VERSION::AMI_ID_64_BIT
|
42
|
+
set :deploy_to, "/mnt/app"
|
43
|
+
set :use_sudo, false
|
44
|
+
set :user, "app"
|
45
|
+
|
46
|
+
# make an "admin" role for each role, and create arrays containing
|
47
|
+
# the names of admin roles and non-admin roles for convenience
|
48
|
+
set :all_admin_role_names, []
|
49
|
+
set :all_non_admin_role_names, []
|
50
|
+
roles.keys.clone.each do |name|
|
51
|
+
make_admin_role_for(name)
|
52
|
+
all_non_admin_role_names << name
|
53
|
+
all_admin_role_names << "#{name.to_s}_admin".to_sym
|
54
|
+
end
|
55
|
+
|
56
|
+
after "deploy:symlink", "ec2onrails:server:set_roles"
|
57
|
+
after "deploy:cold", "ec2onrails:db:init_backup"
|
58
|
+
|
59
|
+
# override default start/stop/restart tasks
|
60
|
+
namespace :deploy do
|
61
|
+
desc <<-DESC
|
62
|
+
Overrides the default Capistrano deploy:restart, uses \
|
63
|
+
/etc/init.d/mongrel
|
64
|
+
DESC
|
65
|
+
task :start, :roles => :app_admin do
|
66
|
+
run_init_script("mongrel", "start")
|
67
|
+
run "sleep 30" # give the service 30 seconds to start before attempting to monitor it
|
68
|
+
sudo "monit -g app monitor all"
|
69
|
+
end
|
70
|
+
|
71
|
+
desc <<-DESC
|
72
|
+
Overrides the default Capistrano deploy:restart, uses \
|
73
|
+
/etc/init.d/mongrel
|
74
|
+
DESC
|
75
|
+
task :stop, :roles => :app_admin do
|
76
|
+
sudo "monit -g app unmonitor all"
|
77
|
+
run_init_script("mongrel", "stop")
|
78
|
+
end
|
79
|
+
|
80
|
+
desc <<-DESC
|
81
|
+
Overrides the default Capistrano deploy:restart, uses \
|
82
|
+
/etc/init.d/mongrel
|
83
|
+
DESC
|
84
|
+
task :restart, :roles => :app_admin do
|
85
|
+
deploy.stop
|
86
|
+
deploy.start
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
namespace :ec2onrails do
|
91
|
+
desc <<-DESC
|
92
|
+
Show the AMI id's of the current images for this version of \
|
93
|
+
EC2 on Rails.
|
94
|
+
DESC
|
95
|
+
task :ami_ids do
|
96
|
+
puts "32-bit server image for EC2 on Rails #{ec2onrails_version}: #{image_id_32_bit}"
|
97
|
+
puts "64-bit server image for EC2 on Rails #{ec2onrails_version}: #{image_id_64_bit}"
|
98
|
+
end
|
99
|
+
|
100
|
+
desc <<-DESC
|
101
|
+
Copies the public key from the server using the external "ssh"
|
102
|
+
command because Net::SSH, which is used by Capistrano, needs it.
|
103
|
+
This will only work if you have an ssh command in the path.
|
104
|
+
If Capistrano can successfully connect to your EC2 instance you
|
105
|
+
don't need to do this. It will copy from the first server in the
|
106
|
+
:app role, this can be overridden by specifying the HOST
|
107
|
+
environment variable
|
108
|
+
DESC
|
109
|
+
task :get_public_key_from_server do
|
110
|
+
host = find_servers_for_task(current_task).first.host
|
111
|
+
privkey = ssh_options[:keys][0]
|
112
|
+
pubkey = "#{privkey}.pub"
|
113
|
+
msg = <<-MSG
|
114
|
+
Your first key in ssh_options[:keys] is #{privkey}, presumably that's
|
115
|
+
your EC2 private key. The public key will be copied from the server
|
116
|
+
named '#{host}' and saved locally as #{pubkey}. Continue? [y/n]
|
117
|
+
MSG
|
118
|
+
choice = nil
|
119
|
+
while choice != "y" && choice != "n"
|
120
|
+
choice = Capistrano::CLI.ui.ask(msg).downcase
|
121
|
+
msg = "Please enter 'y' or 'n'."
|
122
|
+
end
|
123
|
+
if choice == "y"
|
124
|
+
run_local "scp -i '#{privkey}' app@#{host}:.ssh/authorized_keys #{pubkey}"
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
desc <<-DESC
|
129
|
+
Prepare a newly-started instance for a cold deploy.
|
130
|
+
DESC
|
131
|
+
task :setup, :roles => all_admin_role_names do
|
132
|
+
server.set_admin_mail_forward_address
|
133
|
+
server.set_timezone
|
134
|
+
server.install_packages
|
135
|
+
server.install_gems
|
136
|
+
server.deploy_files
|
137
|
+
server.enable_ssl if cfg[:enable_ssl]
|
138
|
+
server.set_rails_env
|
139
|
+
server.restart_services
|
140
|
+
deploy.setup
|
141
|
+
db.create
|
142
|
+
end
|
143
|
+
|
144
|
+
desc <<-DESC
|
145
|
+
Deploy and restore database from S3
|
146
|
+
DESC
|
147
|
+
task :restore_db_and_deploy do
|
148
|
+
db.recreate
|
149
|
+
deploy.update_code
|
150
|
+
deploy.symlink
|
151
|
+
db.restore
|
152
|
+
deploy.migrations
|
153
|
+
end
|
154
|
+
|
155
|
+
namespace :ec2 do
|
156
|
+
desc <<-DESC
|
157
|
+
DESC
|
158
|
+
task :configure_firewall do
|
159
|
+
# TODO
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
namespace :db do
|
164
|
+
desc <<-DESC
|
165
|
+
[internal] Load configuration info for the database from
|
166
|
+
config/database.yml, and start mysql (it must be running
|
167
|
+
in order to interact with it).
|
168
|
+
DESC
|
169
|
+
task :load_config do
|
170
|
+
unless hostnames_for_role(:db, :primary => true).empty?
|
171
|
+
db_config = YAML::load(ERB.new(File.read("config/database.yml")).result)[rails_env.to_s]
|
172
|
+
cfg[:db_name] = db_config['database']
|
173
|
+
cfg[:db_user] = db_config['username'] || db_config['user']
|
174
|
+
cfg[:db_password] = db_config['password']
|
175
|
+
cfg[:db_host] = db_config['host']
|
176
|
+
cfg[:db_socket] = db_config['socket']
|
177
|
+
|
178
|
+
if (cfg[:db_host].nil? || cfg[:db_host].empty?) && (cfg[:db_socket].nil? || cfg[:db_socket].empty?)
|
179
|
+
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'."
|
180
|
+
end
|
181
|
+
|
182
|
+
[cfg[:db_name], cfg[:db_user], cfg[:db_password]].each do |s|
|
183
|
+
if s.nil? || s.empty?
|
184
|
+
raise "ERROR: missing database config. Make sure database.yml contains a '#{rails_env}' section with a database name, user, and password."
|
185
|
+
elsif s.match(/['"]/)
|
186
|
+
raise "ERROR: database config string '#{s}' contains quotes."
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
desc <<-DESC
|
193
|
+
Create the MySQL database. Assumes there is no MySQL root \
|
194
|
+
password. To create a MySQL root password create a task that's run \
|
195
|
+
after this task using an after hook.
|
196
|
+
DESC
|
197
|
+
task :create, :roles => :db do
|
198
|
+
on_rollback { drop }
|
199
|
+
load_config
|
200
|
+
start
|
201
|
+
|
202
|
+
# For some reason the default db on Hardy contains users with '' as the name.
|
203
|
+
# This causes authentication problems when connecting from localhost
|
204
|
+
run %{mysql -u root -D mysql -e "delete from user where User = ''; flush privileges;"}
|
205
|
+
|
206
|
+
run %{mysql -u root -e "create database if not exists #{cfg[:db_name]};"}
|
207
|
+
run %{mysql -u root -e "grant all on #{cfg[:db_name]}.* to '#{cfg[:db_user]}'@'%' identified by '#{cfg[:db_password]}';"}
|
208
|
+
run %{mysql -u root -e "grant reload on *.* to '#{cfg[:db_user]}'@'%' identified by '#{cfg[:db_password]}';"}
|
209
|
+
run %{mysql -u root -e "grant super on *.* to '#{cfg[:db_user]}'@'%' identified by '#{cfg[:db_password]}';"}
|
210
|
+
end
|
211
|
+
|
212
|
+
desc <<-DESC
|
213
|
+
[internal] Make sure the MySQL server has been started, just in case the db role
|
214
|
+
hasn't been set, e.g. when called from ec2onrails:setup.
|
215
|
+
(But don't enable monitoring on it.)
|
216
|
+
DESC
|
217
|
+
task :start, :roles => :db_admin do
|
218
|
+
sudo "chmod a+x /etc/init.d/mysql"
|
219
|
+
# The mysql init script can fail on the first startup if mysql takes too long
|
220
|
+
# to create the logfiles, so try again
|
221
|
+
sudo "sh -c '/etc/init.d/mysql start || (sleep 10 && /etc/init.d/mysql start)'"
|
222
|
+
end
|
223
|
+
|
224
|
+
desc <<-DESC
|
225
|
+
Drop the MySQL database. Assumes there is no MySQL root \
|
226
|
+
password. If there is a MySQL root password, create a task that removes \
|
227
|
+
it and run that task before this one using a before hook.
|
228
|
+
DESC
|
229
|
+
task :drop, :roles => :db do
|
230
|
+
load_config
|
231
|
+
run %{mysql -u root -e "drop database if exists #{cfg[:db_name]};"}
|
232
|
+
end
|
233
|
+
|
234
|
+
desc <<-DESC
|
235
|
+
db:drop and db:create.
|
236
|
+
DESC
|
237
|
+
task :recreate, :roles => :db do
|
238
|
+
drop
|
239
|
+
create
|
240
|
+
end
|
241
|
+
|
242
|
+
desc <<-DESC
|
243
|
+
Set a root password for MySQL, using the variable mysql_root_password \
|
244
|
+
if it is set. If this is done db:drop won't work.
|
245
|
+
DESC
|
246
|
+
task :set_root_password, :roles => :db do
|
247
|
+
if cfg[:mysql_root_password]
|
248
|
+
run %{mysql -u root -e "UPDATE mysql.user SET Password=PASSWORD('#{cfg[:mysql_root_password]}') WHERE User='root'; FLUSH PRIVILEGES;"}
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
desc <<-DESC
|
253
|
+
Dump the MySQL database to the S3 bucket specified by \
|
254
|
+
ec2onrails_config[:archive_to_bucket]. The filename will be \
|
255
|
+
"database-archive/<timestamp>/dump.sql.gz".
|
256
|
+
DESC
|
257
|
+
task :archive, :roles => :db do
|
258
|
+
run "/usr/local/ec2onrails/bin/backup_app_db.rb --bucket #{cfg[:archive_to_bucket]} --dir #{cfg[:archive_to_bucket_subdir]}"
|
259
|
+
end
|
260
|
+
|
261
|
+
desc <<-DESC
|
262
|
+
Restore the MySQL database from the S3 bucket specified by \
|
263
|
+
ec2onrails_config[:restore_from_bucket]. The archive filename is \
|
264
|
+
expected to be the default, "mysqldump.sql.gz".
|
265
|
+
DESC
|
266
|
+
task :restore, :roles => :db do
|
267
|
+
run "/usr/local/ec2onrails/bin/restore_app_db.rb --bucket #{cfg[:restore_from_bucket]} --dir #{cfg[:restore_from_bucket_subdir]}"
|
268
|
+
end
|
269
|
+
|
270
|
+
desc <<-DESC
|
271
|
+
[internal] Initialize the default backup folder on S3 (i.e. do a full
|
272
|
+
backup of the newly-created db so the automatic incremental backups
|
273
|
+
make sense).
|
274
|
+
DESC
|
275
|
+
task :init_backup, :roles => :db do
|
276
|
+
run "/usr/local/ec2onrails/bin/backup_app_db.rb --reset"
|
277
|
+
end
|
278
|
+
end
|
279
|
+
|
280
|
+
namespace :server do
|
281
|
+
desc <<-DESC
|
282
|
+
Tell the servers what roles they are in. This configures them with \
|
283
|
+
the appropriate settings for each role, and starts and/or stops the \
|
284
|
+
relevant services.
|
285
|
+
DESC
|
286
|
+
task :set_roles, :roles => all_admin_role_names do
|
287
|
+
# TODO generate this based on the roles that actually exist so arbitrary new ones can be added
|
288
|
+
roles = {
|
289
|
+
:web => hostnames_for_role(:web),
|
290
|
+
:app => hostnames_for_role(:app),
|
291
|
+
:db_primary => hostnames_for_role(:db, :primary => true),
|
292
|
+
:memcache => hostnames_for_role(:memcache)
|
293
|
+
}
|
294
|
+
roles_yml = YAML::dump(roles)
|
295
|
+
put roles_yml, "/tmp/roles.yml"
|
296
|
+
sudo "cp /tmp/roles.yml /etc/ec2onrails"
|
297
|
+
sudo "/usr/local/ec2onrails/bin/set_roles.rb"
|
298
|
+
end
|
299
|
+
|
300
|
+
desc <<-DESC
|
301
|
+
Change the default value of RAILS_ENV on the server. Technically
|
302
|
+
this changes the server's mongrel config to use a different value
|
303
|
+
for "environment". The value is specified in :rails_env.
|
304
|
+
Be sure to do deploy:restart after this.
|
305
|
+
DESC
|
306
|
+
task :set_rails_env, :roles => all_admin_role_names do
|
307
|
+
rails_env = fetch(:rails_env, "production")
|
308
|
+
sudo "/usr/local/ec2onrails/bin/set_rails_env #{rails_env}"
|
309
|
+
end
|
310
|
+
|
311
|
+
desc <<-DESC
|
312
|
+
Upgrade to the newest versions of all Ubuntu packages.
|
313
|
+
DESC
|
314
|
+
task :upgrade_packages, :roles => all_admin_role_names do
|
315
|
+
sudo "aptitude -q update"
|
316
|
+
run "export DEBIAN_FRONTEND=noninteractive; sudo aptitude -q -y safe-upgrade"
|
317
|
+
end
|
318
|
+
|
319
|
+
desc <<-DESC
|
320
|
+
Upgrade to the newest versions of all rubygems.
|
321
|
+
DESC
|
322
|
+
task :upgrade_gems, :roles => all_admin_role_names do
|
323
|
+
sudo "gem update --system --no-rdoc --no-ri"
|
324
|
+
sudo "gem update --no-rdoc --no-ri" do |ch, str, data|
|
325
|
+
ch[:data] ||= ""
|
326
|
+
ch[:data] << data
|
327
|
+
if data =~ />\s*$/
|
328
|
+
puts data
|
329
|
+
choice = Capistrano::CLI.ui.ask("The gem command is asking for a number:")
|
330
|
+
ch.send_data("#{choice}\n")
|
331
|
+
else
|
332
|
+
puts data
|
333
|
+
end
|
334
|
+
end
|
335
|
+
|
336
|
+
end
|
337
|
+
|
338
|
+
desc <<-DESC
|
339
|
+
Install extra Ubuntu packages. Set ec2onrails_config[:packages], it \
|
340
|
+
should be an array of strings.
|
341
|
+
NOTE: the package installation will be non-interactive, if the packages \
|
342
|
+
require configuration either log in as 'admin' and run \
|
343
|
+
'dpkg-reconfigure packagename' or replace the package's config files \
|
344
|
+
using the 'ec2onrails:server:deploy_files' task.
|
345
|
+
DESC
|
346
|
+
task :install_packages, :roles => all_admin_role_names do
|
347
|
+
if cfg[:packages] && cfg[:packages].any?
|
348
|
+
run "export DEBIAN_FRONTEND=noninteractive; sudo aptitude -q -y install #{cfg[:packages].join(' ')}"
|
349
|
+
end
|
350
|
+
end
|
351
|
+
|
352
|
+
desc <<-DESC
|
353
|
+
Install extra rubygems. Set ec2onrails_config[:rubygems], it should \
|
354
|
+
be with an array of strings.
|
355
|
+
DESC
|
356
|
+
task :install_gems, :roles => all_admin_role_names do
|
357
|
+
if cfg[:rubygems]
|
358
|
+
cfg[:rubygems].each do |gem|
|
359
|
+
sudo "gem install #{gem} --no-rdoc --no-ri" do |ch, str, data|
|
360
|
+
ch[:data] ||= ""
|
361
|
+
ch[:data] << data
|
362
|
+
if data =~ />\s*$/
|
363
|
+
puts data
|
364
|
+
choice = Capistrano::CLI.ui.ask("The gem command is asking for a number:")
|
365
|
+
ch.send_data("#{choice}\n")
|
366
|
+
else
|
367
|
+
puts data
|
368
|
+
end
|
369
|
+
end
|
370
|
+
end
|
371
|
+
end
|
372
|
+
end
|
373
|
+
|
374
|
+
desc <<-DESC
|
375
|
+
A convenience task to upgrade existing packages and gems and install \
|
376
|
+
specified new ones.
|
377
|
+
DESC
|
378
|
+
task :upgrade_and_install_all, :roles => all_admin_role_names do
|
379
|
+
upgrade_packages
|
380
|
+
upgrade_gems
|
381
|
+
install_packages
|
382
|
+
install_gems
|
383
|
+
end
|
384
|
+
|
385
|
+
desc <<-DESC
|
386
|
+
Set the timezone using the value of the variable named timezone. \
|
387
|
+
Valid options for timezone can be determined by the contents of \
|
388
|
+
/usr/share/zoneinfo, which can be seen here: \
|
389
|
+
http://packages.ubuntu.com/cgi-bin/search_contents.pl?searchmode=filelist&word=tzdata&version=gutsy&arch=all&page=1&number=all \
|
390
|
+
Remove 'usr/share/zoneinfo/' from the filename, and use the last \
|
391
|
+
directory and file as the value. For example 'Africa/Abidjan' or \
|
392
|
+
'posix/GMT' or 'Canada/Eastern'.
|
393
|
+
DESC
|
394
|
+
task :set_timezone, :roles => all_admin_role_names do
|
395
|
+
if cfg[:timezone]
|
396
|
+
sudo "bash -c 'echo #{cfg[:timezone]} > /etc/timezone'"
|
397
|
+
sudo "cp /usr/share/zoneinfo/#{cfg[:timezone]} /etc/localtime"
|
398
|
+
end
|
399
|
+
end
|
400
|
+
|
401
|
+
desc <<-DESC
|
402
|
+
Deploy a set of config files to the server, the files will be owned by \
|
403
|
+
root. This doesn't delete any files from the server. This is intended
|
404
|
+
mainly for customized config files for new packages installed via the \
|
405
|
+
ec2onrails:server:install_packages task. Subdirectories and files \
|
406
|
+
inside here will be placed within the same directory structure \
|
407
|
+
relative to the root of the server's filesystem.
|
408
|
+
DESC
|
409
|
+
task :deploy_files, :roles => all_admin_role_names do
|
410
|
+
if cfg[:server_config_files_root]
|
411
|
+
begin
|
412
|
+
filename = "config_files.tar"
|
413
|
+
local_file = "#{Dir.tmpdir}/#{filename}"
|
414
|
+
remote_file = "/tmp/#{filename}"
|
415
|
+
FileUtils.cd(cfg[:server_config_files_root]) do
|
416
|
+
File.open(local_file, 'wb') { |tar| Minitar.pack(".", tar) }
|
417
|
+
end
|
418
|
+
put File.read(local_file), remote_file
|
419
|
+
sudo "tar xvf #{remote_file} -o -C /"
|
420
|
+
ensure
|
421
|
+
rm_rf local_file
|
422
|
+
run "rm -f #{remote_file}"
|
423
|
+
end
|
424
|
+
end
|
425
|
+
end
|
426
|
+
|
427
|
+
desc <<-DESC
|
428
|
+
Restart a set of services. Set ec2onrails_config[:services_to_restart] \
|
429
|
+
to an array of strings. It's assumed that each service has a script \
|
430
|
+
in /etc/init.d
|
431
|
+
DESC
|
432
|
+
task :restart_services, :roles => all_admin_role_names do
|
433
|
+
if cfg[:services_to_restart] && cfg[:services_to_restart].any?
|
434
|
+
cfg[:services_to_restart].each do |service|
|
435
|
+
run_init_script(service, "restart")
|
436
|
+
end
|
437
|
+
end
|
438
|
+
end
|
439
|
+
|
440
|
+
desc <<-DESC
|
441
|
+
Set the email address that mail to the admin user forwards to.
|
442
|
+
DESC
|
443
|
+
task :set_admin_mail_forward_address, :roles => all_admin_role_names do
|
444
|
+
put cfg[:admin_mail_forward_address], "/home/admin/.forward" if cfg[:admin_mail_forward_address]
|
445
|
+
end
|
446
|
+
|
447
|
+
desc <<-DESC
|
448
|
+
Enable ssl for the web server. The SSL cert file should be in
|
449
|
+
/etc/ssl/certs/default.pem and the SSL key file should be in
|
450
|
+
/etc/ssl/private/default.key (use the deploy_files task).
|
451
|
+
DESC
|
452
|
+
task :enable_ssl, :roles => :web_admin do
|
453
|
+
sudo "a2enmod ssl"
|
454
|
+
sudo "a2ensite default-ssl"
|
455
|
+
run_init_script("apache2", "restart")
|
456
|
+
end
|
457
|
+
end
|
458
|
+
|
459
|
+
end
|
460
|
+
end
|