forked from mbailey/deprec
-
Notifications
You must be signed in to change notification settings - Fork 0
/
rails.rb
286 lines (240 loc) · 10.5 KB
/
rails.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
# Copyright 2006-2008 by Mike Bailey. All rights reserved.
Capistrano::Configuration.instance(:must_exist).load do
set :app_user_prefix, 'app_'
set(:app_user) { app_user_prefix + application }
set :app_group_prefix, 'app_'
set(:app_group) { app_group_prefix + application }
set(:app_user_homedir) { deploy_to }
set :database_yml_in_scm, false
set :app_symlinks, nil
set :rails_env, 'production'
set :gems_for_project, nil # Array of gems to be installed for app
set :packages_for_project, nil # Array of packages to be installed for app
set :shared_dirs, nil # Array of directories that should be created under shared/
# and linked to in the project
# Hook into the default capistrano deploy tasks
before 'deploy:setup', :except => { :no_release => true } do
top.deprec.rails.setup_user_perms
top.deprec.rails.create_app_user_and_group
top.deprec.rails.setup_paths
top.deprec.rails.setup_shared_dirs
top.deprec.rails.install_packages_for_project
top.deprec.rails.install_gems_for_project
end
after 'deploy:setup', :except => { :no_release => true } do
top.deprec.rails.create_config_dir
top.deprec.rails.config_gen
top.deprec.rails.config
top.deprec.rails.activate_services
top.deprec.rails.set_perms_on_shared_and_releases
top.deprec.web.reload
top.deprec.rails.setup_database
end
after 'deploy:update_code', :roles => :app do
top.deprec.rails.symlink_shared_dirs
top.deprec.rails.symlink_database_yml unless database_yml_in_scm
top.deprec.rails.make_writable_by_app
top.deprec.passenger.set_owner_of_environment_rb if app_server_type.to_s == 'passenger'
end
after :deploy, "deploy:cleanup"
namespace :deprec do
namespace :rails do
task :install, :roles => :app do
apt.install( { :base => %w(libmysqlclient15-dev sqlite3 libsqlite3-ruby libsqlite3-dev libpq-dev) }, :stable)
gem2.install 'bundler'
end
desc "Install Ruby on Rails stack on Ubuntu server (8.04, 10.04)"
task :install_stack do
puts "deprecated: renamed to deprec:rack:install_stack"
top.deprec.rack.install_stack
end
task :install_rails_stack do
puts "deprecated: renamed to deprec:rack:install_stack"
top.deprec.rack.install_stack
end
#
# If database.yml is not kept in scm and it is present in local
# config dir then push it out to server.
#
before 'deprec:rails:symlink_database_yml', :roles => :app do
push_database_yml unless database_yml_in_scm
end
task :setup_database, :roles => :db do
if ! roles[:db].servers.empty? # Some apps don't use database!
deprec2.read_database_yml
top.deprec.db.create_user
top.deprec.db.create_database
top.deprec.db.grant_user_access_to_database
end
end
desc "Generate config files for rails app."
task :config_gen do
top.deprec.web.config_gen_project
top.deprec.app.config_gen_project
end
desc "Push out config files for rails app."
task :config do
top.deprec.web.config_project
top.deprec.app.config_project
end
task :create_config_dir, :roles => :app do
deprec2.mkdir("#{shared_path}/config", :group => group, :mode => 0775, :via => :sudo)
end
# XXX This should be restricted a bit to limit what app can write to. - Mike
desc "set group ownership and permissions on dirs app server needs to write to"
task :make_writable_by_app, :roles => :app do
dirs = "#{shared_path} #{current_path}/tmp #{current_path}/public"
sudo "chgrp -R #{app_group} #{dirs}"
sudo "chmod -R g+w #{dirs}"
# set owner and group of log files
# XXX Factor out mongrel
files = ["#{mongrel_log_dir}/mongrel.log", "#{mongrel_log_dir}/#{rails_env}.log"]
files.each { |file|
sudo "touch #{file}"
sudo "chown #{app_user} #{file}"
sudo "chgrp #{app_group} #{file}"
sudo "chmod g+w #{file}"
}
end
desc "Create deployment group and add current user to it"
task :setup_user_perms, :roles => [:app, :web] do
deprec2.groupadd(group)
deprec2.add_user_to_group(user, group)
deprec2.groupadd(app_group)
deprec2.add_user_to_group(user, app_group)
# we've just added ourself to a group - need to teardown connection
# so that next command uses new session where we belong in group
deprec2.teardown_connections
end
desc "Create user and group for application to run as"
task :create_app_user_and_group, :roles => :app do
deprec2.groupadd(app_group)
deprec2.useradd(app_user, :group => app_group, :homedir => false)
# Set the primary group for the user the application runs as (in case
# user already existed when previous command was run)
sudo "usermod --gid #{app_group} --home #{app_user_homedir} #{app_user}"
end
task :set_perms_on_shared_and_releases, :roles => :app do
releases = File.join(deploy_to, 'releases')
sudo "chgrp -R #{group} #{shared_path} #{releases}"
sudo "chmod -R g+w #{shared_path} #{releases}"
end
# Setup database server.
task :setup_db, :roles => :db, :only => { :primary => true } do
top.deprec.mysql.setup
end
# setup extra paths required for deployment
task :setup_paths, :roles => [:app, :web] do
deprec2.mkdir(deploy_to, :mode => 0775, :group => group, :via => :sudo)
deprec2.mkdir(shared_path, :mode => 0775, :group => group, :via => :sudo)
end
# Symlink list of files and dirs from shared to current
#
# XXX write up explanation
#
desc "Setup shared dirs"
task :setup_shared_dirs, :roles => [:app, :web] do
if shared_dirs
shared_dirs.each { |dir| deprec2.mkdir( "#{shared_path}/#{dir}", :via => :sudo ) }
end
end
#
desc "Symlink shared dirs."
task :symlink_shared_dirs, :roles => [:app, :web] do
if shared_dirs
shared_dirs.each do |dir|
path = File.split(dir)[0]
if path != '.'
deprec2.mkdir("#{current_path}/#{path}")
end
sudo "test -d #{current_path}/#{dir} && mv #{current_path}/#{dir} #{current_path}/#{dir}.moved_by_deprec; exit 0"
run "ln -nfs #{shared_path}/#{dir} #{current_path}/#{dir}"
end
end
end
task :install_packages_for_project, :roles => :app do
if packages_for_project
apt.install({ :base => packages_for_project }, :stable)
end
end
task :install_gems_for_project, :roles => :app do
if gems_for_project
gems_for_project.each { |gem| gem2.install(gem) }
end
end
desc "Activate web, app and monit"
task :activate_services do
top.deprec.web.activate
top.deprec.app.activate
# top.deprec.monit.activate
end
# database.yml stuff
#
# XXX DRY this up
# I don't know how to let :gen_db_yml check if values have been set.
#
# if (self.respond_to?("db_host_#{rails_env}".to_sym)) # doesn't seem to work
set :db_host_default, lambda { Capistrano::CLI.prompt 'Enter database host', 'localhost'}
set :db_host_staging, lambda { db_host_default }
set :db_host_production, lambda { db_host_default }
set :db_name_default, lambda { Capistrano::CLI.prompt 'Enter database name', "#{application}_#{rails_env}" }
set :db_name_staging, lambda { db_name_default }
set :db_name_production, lambda { db_name_default }
set :db_user_default, lambda { Capistrano::CLI.prompt 'Enter database user', 'root' }
set :db_user_staging, lambda { db_user_default }
set :db_user_production, lambda { db_user_default }
set :db_pass_default, lambda { Capistrano::CLI.prompt 'Enter database pass', '' }
set :db_pass_staging, lambda { db_pass_default }
set :db_pass_production, lambda { db_pass_default }
set :db_adaptor_default, lambda { Capistrano::CLI.prompt 'Enter database adaptor', 'mysql' }
set :db_adaptor_staging, lambda { db_adaptor_default }
set :db_adaptor_production, lambda { db_adaptor_default }
set :db_socket_default, lambda { Capistrano::CLI.prompt('Enter database socket', '')}
set :db_socket_staging, lambda { db_socket_default }
set :db_socket_production, lambda { db_socket_default }
task :generate_database_yml, :roles => :app do
database_configuration = render :template => <<-EOF
#{rails_env}:
adapter: #{self.send("db_adaptor_#{rails_env}")}
database: #{self.send("db_name_#{rails_env}")}
username: #{self.send("db_user_#{rails_env}")}
password: #{self.send("db_pass_#{rails_env}")}
host: #{self.send("db_host_#{rails_env}")}
socket: #{self.send("db_socket_#{rails_env}")}
EOF
run "mkdir -p #{deploy_to}/#{shared_dir}/config"
put database_configuration, "#{deploy_to}/#{shared_dir}/config/database.yml"
end
desc "Link in the production database.yml"
task :symlink_database_yml, :roles => :app do
run "#{sudo} ln -nfs #{shared_path}/config/database.yml #{release_path}/config/database.yml"
end
desc "Copy database.yml to shared/config/database.yml. Useful if not kept in scm"
task :push_database_yml, :roles => :app do
stage = exists?(:stage) ? fetch(:stage).to_s : ''
full_local_path = File.join('config', stage, 'database.yml')
if File.exists?(full_local_path)
std.su_put(File.read(full_local_path), "#{shared_path}/config/database.yml", '/tmp/')
end
end
end
namespace :database do
desc "Create database"
task :create, :roles => :app do
run "cd #{deploy_to}/current && rake db:create RAILS_ENV=#{rails_env}"
end
desc "Run database migrations"
task :migrate, :roles => :app do
run "cd #{deploy_to}/current && rake db:migrate RAILS_ENV=#{rails_env}"
end
desc "Run database migrations"
task :schema_load, :roles => :app do
run "cd #{deploy_to}/current && rake db:schema:load RAILS_ENV=#{rails_env}"
end
desc "Roll database back to previous migration"
task :rollback, :roles => :app do
run "cd #{deploy_to}/current && rake db:rollback RAILS_ENV=#{rails_env}"
end
end
end
end