-
-
Notifications
You must be signed in to change notification settings - Fork 40
/
capistrano.rb
320 lines (259 loc) · 10.5 KB
/
capistrano.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
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
# Recipes for using RVM on a server with capistrano.
require 'rvm/capistrano/selector'
module Capistrano
Configuration.instance(true).load do
unless methods.map(&:to_sym).include?(:_cset)
# Taken from the capistrano code.
def _cset(name, *args, &block)
unless exists?(name)
set(name, *args, &block)
end
end
end
class << self
def quote_and_escape(text, quote = "'")
"#{quote}#{text.gsub(/#{quote}/) { |m| "#{quote}\\#{quote}#{quote}" }}#{quote}"
end
end
# this is part of check, search for :rvm_require_role
unless fetch(:rvm_require_role,nil).nil?
set :rvm_require_role_was_set_before_require, true
class << self
def run(cmd, options={}, &block)
if options[:eof].nil? && !cmd.include?(sudo)
options = options.merge(:eof => !block_given?)
end
shell = options[:shell]
options[:shell] = false
parallel(options) do |session|
if shell.nil?
session.when "in?(:#{fetch(:rvm_require_role,nil)})", command_with_shell(cmd, fetch(:rvm_shell)), &block
end
session.else command_with_shell(cmd, shell), &block
end
end
def command_with_shell(cmd, shell=nil)
if shell == false
cmd
else
"#{shell || "sh"} -c #{quote_and_escape(cmd)}"
end
end
end
end
on :load do
# this is part of check, search for :rvm_require_role
if ! fetch(:rvm_require_role,nil).nil? and fetch(:rvm_require_role_was_set_before_require, nil).nil?
raise "
ERROR: detected 'set :rvm_require_role, \"#{fetch(:rvm_require_role,nil)}\"' after 'require \"rvm/capistrano\"', please move it above for proper functioning.
"
end
# Let users configure a path to export/import gemsets
_cset(:rvm_gemset_path, "#{rvm_path}/gemsets")
# Default sudo state
_cset(:rvm_install_with_sudo, false)
# Let users set the install type and shell of their choice.
_cset(:rvm_install_type, :stable)
_cset(:rvm_install_shell, :bash)
# Let users set the (re)install for ruby.
_cset(:rvm_install_ruby, :install)
# Pass no special params to the ruby build by default
_cset(:rvm_install_ruby_params, '')
# Additional rvm packages to install.
_cset(:rvm_install_pkgs, [])
# By default system installations add deploying user to rvm group. also try :all
_cset(:rvm_add_to_group, fetch(:user,"$USER"))
end
namespace :rvm do
def run_silent_curl(command)
run(<<-EOF.gsub(/[\s]+/, ' '), :shell => "#{rvm_install_shell}")
__LAST_STATUS=0;
export CURL_HOME="${TMPDIR:-${HOME}}/.rvm-curl-config.$$";
mkdir ${CURL_HOME}/;
{
[[ -r ${HOME}/.curlrc ]] && cat ${HOME}/.curlrc;
echo "silent";
echo "show-error";
} > $CURL_HOME/.curlrc;
#{command} || __LAST_STATUS=$?;
rm -rf $CURL_HOME;
exit ${__LAST_STATUS}
EOF
end
def rvm_if_sudo(options = {})
case rvm_type
when :root, :system
if fetch(:use_sudo, true) == false && rvm_install_with_sudo == false
explanation = <<-EXPLANATION
You can enable use_sudo within rvm for use only by this install operation by adding to deploy.rb:
set :rvm_install_with_sudo, true
EXPLANATION
if options[:deferred]
<<-DEFERRED_ERROR.gsub(/\n/, " ; ")
echo "
Neither :use_sudo or :rvm_install_with_sudo was set and installation would ended up in using 'sudo'
#{explanation}
" >&2
exit 1
DEFERRED_ERROR
else
raise "
:use_sudo is set to 'false' but sudo is needed to install rvm_type: #{rvm_type}.
#{explanation}
"
end
else
"#{sudo} "
end
else
''
end
end
def with_rvm_group(command)
case rvm_type
when :root, :system
<<-CODE
if id | grep ' groups=.*(rvm)' >/dev/null ;
then #{command} ;
else #{rvm_if_sudo(:deferred=>true)} sg rvm -c #{quote_and_escape(command)} ;
fi
CODE
else
command
end
end
def rvm_task(name,&block)
if fetch(:rvm_require_role,nil).nil?
task name, &block
else
task name, :roles => fetch(:rvm_require_role), &block
end
end
desc <<-EOF
Install RVM of the given choice to the server.
By default RVM "stable" is installed, change with:
set :rvm_install_type, :head
By default BASH is used for installer, change with:
set :rvm_install_shell, :zsh
EOF
rvm_task :install_rvm do
command_fetch = "curl -L get.rvm.io"
command_install = rvm_if_sudo
command_install << "#{rvm_install_shell} -s #{rvm_install_type} --path #{rvm_path}"
case rvm_type
when :root, :system
command_install << " --add-to-rvm-group #{[rvm_add_to_group].flatten.map(&:to_s).join(",")}"
end
run_silent_curl "#{command_fetch} | #{command_install}"
end
desc <<-EOF
Install RVM ruby to the server, create gemset if needed.
By default ruby is installed, you can reinstall with:
set :rvm_install_ruby, :reinstall
By default ruby is compiled using all CPU cores, change with:
set :rvm_install_ruby_threads, 5
By default BASH is used for installer, change with:
set :rvm_install_shell, :zsh
EOF
rvm_task :install_ruby do
ruby, gemset = fetch(:rvm_ruby_string_evaluated).to_s.strip.split(/@/)
if %w( release_path default ).include? "#{ruby}"
raise "
ruby can not be installed when using :rvm_ruby_string => :#{ruby}
"
else
command_install = ""
autolibs_flag = fetch(:rvm_autolibs_flag, 2).to_s
autolibs_flag_no_requirements = %w(
0 disable disabled
1 read read-only
2 fail read-fail
).include?( autolibs_flag )
install_ruby_threads = fetch(:rvm_install_ruby_threads,nil).nil? ? '' : "-j #{rvm_install_ruby_threads}"
if autolibs_flag_no_requirements
command_install << with_rvm_group("#{File.join(rvm_bin_path, "rvm")} --autolibs=#{autolibs_flag} #{rvm_install_ruby} #{ruby} #{install_ruby_threads} #{rvm_install_ruby_params}")
else
command_install << "#{rvm_if_sudo} #{File.join(rvm_bin_path, "rvm")} --autolibs=#{autolibs_flag} requirements #{ruby}"
command_install << "; "
command_install << with_rvm_group("#{File.join(rvm_bin_path, "rvm")} --autolibs=1 #{rvm_install_ruby} #{ruby} #{install_ruby_threads} #{rvm_install_ruby_params}")
end
if gemset
command_install << "; "
command_install << with_rvm_group("#{File.join(rvm_bin_path, "rvm")} #{ruby} do rvm gemset create #{gemset}")
end
run_silent_curl command_install
end
end
desc <<-EOF
Install RVM packages to the server.
This must come before the 'rvm:install_ruby' task is called.
The package list is empty by default. Specifiy the packages to install with:
set :rvm_install_pkgs, %w[libyaml curl]
Full list of packages available at https://rvm.io/packages/ or by running 'rvm pkg'.
EOF
rvm_task :install_pkgs do
rvm_install_pkgs.each do |pkg|
run "#{File.join(rvm_bin_path, "rvm")} pkg install #{pkg}", :shell => "#{rvm_install_shell}"
end
end
desc "Create gemset"
rvm_task :create_gemset do
ruby, gemset = fetch(:rvm_ruby_string_evaluated).to_s.strip.split(/@/)
if %w( release_path default ).include? "#{ruby}"
raise "
gemset can not be created when using :rvm_ruby_string => :#{ruby}
"
else
if gemset
run with_rvm_group("#{File.join(rvm_bin_path, "rvm")} #{ruby} do rvm gemset create #{gemset}"), :shell => "#{rvm_install_shell}"
end
end
end
desc <<-EOF
Import file contents to the current RVM ruby gemset.
The gemset filename must match :rvm_ruby_string.gems and be located in :rvm_gemset_path.
:rvm_gemset_path defaults to :rvm_path/gemsets
The gemset can be created with 'cap rvm:gemset_export'.
EOF
rvm_task :import_gemset do
ruby, gemset = fetch(:rvm_ruby_string_evaluated).to_s.strip.split(/@/)
if %w( release_path default ).include? "#{ruby}"
raise "gemset can not be imported when using :rvm_ruby_string => :#{ruby}"
else
if gemset
run "#{File.join(rvm_bin_path, "rvm-shell")} #{fetch(:rvm_ruby_string_evaluated)} rvm gemset import #{File.join(rvm_gemset_path, "#{fetch(:rvm_ruby_string_evaluated)}.gems")}", :shell => "#{rvm_install_shell}"
end
end
end
desc <<-EOF
Export the current RVM ruby gemset contents to a file.
The gemset filename will match :rvm_ruby_string.gems and be located in :rvm_gemset_path.
:rvm_gemset_path defaults to :rvm_path/gemsets
The gemset can be imported with 'cap rvm:gemset_import'.
EOF
rvm_task :export_gemset do
ruby, gemset = fetch(:rvm_ruby_string_evaluated).to_s.strip.split(/@/)
if %w( release_path default ).include? "#{ruby}"
raise "gemset can not be imported when using :rvm_ruby_string => :#{ruby}"
else
if gemset
run "#{File.join(rvm_bin_path, "rvm-shell")} #{fetch(:rvm_ruby_string_evaluated)} rvm gemset export > #{File.join(rvm_gemset_path, "#{fetch(:rvm_ruby_string_evaluated)}.gems")}", :shell => "#{rvm_install_shell}"
end
end
end
desc "Install a gem, 'cap rvm:install_gem GEM=my_gem'."
rvm_task :install_gem do
run "#{File.join(rvm_bin_path, "rvm")} #{fetch(:rvm_ruby_string_evaluated)} do gem install #{ENV['GEM']}", :shell => "#{rvm_install_shell}"
end
desc "Uninstall a gem, 'cap rvm:uninstall_gem GEM=my_gem'."
rvm_task :uninstall_gem do
run "#{File.join(rvm_bin_path, "rvm")} #{fetch(:rvm_ruby_string_evaluated)} do gem uninstall --no-executables #{ENV['GEM']}", :shell => "#{rvm_install_shell}"
end
end
end if Capistrano.const_defined? :Configuration and Capistrano::Configuration.methods.map(&:to_sym).include? :instance
end
# E.g, to use ree and rails 3:
#
# require 'rvm/capistrano'
# set :rvm_ruby_string, "ree@rails3"
#