sunshine 1.0.0.pre
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/History.txt +237 -0
- data/Manifest.txt +70 -0
- data/README.txt +277 -0
- data/Rakefile +46 -0
- data/bin/sunshine +5 -0
- data/examples/deploy.rb +61 -0
- data/examples/deploy_tasks.rake +112 -0
- data/examples/standalone_deploy.rb +31 -0
- data/lib/commands/add.rb +96 -0
- data/lib/commands/default.rb +169 -0
- data/lib/commands/list.rb +322 -0
- data/lib/commands/restart.rb +62 -0
- data/lib/commands/rm.rb +83 -0
- data/lib/commands/run.rb +151 -0
- data/lib/commands/start.rb +72 -0
- data/lib/commands/stop.rb +61 -0
- data/lib/sunshine/app.rb +876 -0
- data/lib/sunshine/binder.rb +70 -0
- data/lib/sunshine/crontab.rb +143 -0
- data/lib/sunshine/daemon.rb +380 -0
- data/lib/sunshine/daemons/ar_sendmail.rb +28 -0
- data/lib/sunshine/daemons/delayed_job.rb +30 -0
- data/lib/sunshine/daemons/nginx.rb +104 -0
- data/lib/sunshine/daemons/rainbows.rb +35 -0
- data/lib/sunshine/daemons/server.rb +66 -0
- data/lib/sunshine/daemons/unicorn.rb +26 -0
- data/lib/sunshine/dependencies.rb +103 -0
- data/lib/sunshine/dependency_lib.rb +200 -0
- data/lib/sunshine/exceptions.rb +54 -0
- data/lib/sunshine/healthcheck.rb +83 -0
- data/lib/sunshine/output.rb +131 -0
- data/lib/sunshine/package_managers/apt.rb +48 -0
- data/lib/sunshine/package_managers/dependency.rb +349 -0
- data/lib/sunshine/package_managers/gem.rb +54 -0
- data/lib/sunshine/package_managers/yum.rb +62 -0
- data/lib/sunshine/remote_shell.rb +241 -0
- data/lib/sunshine/repo.rb +128 -0
- data/lib/sunshine/repos/git_repo.rb +122 -0
- data/lib/sunshine/repos/rsync_repo.rb +29 -0
- data/lib/sunshine/repos/svn_repo.rb +78 -0
- data/lib/sunshine/server_app.rb +554 -0
- data/lib/sunshine/shell.rb +384 -0
- data/lib/sunshine.rb +391 -0
- data/templates/logrotate/logrotate.conf.erb +11 -0
- data/templates/nginx/nginx.conf.erb +109 -0
- data/templates/nginx/nginx_optimize.conf +23 -0
- data/templates/nginx/nginx_proxy.conf +13 -0
- data/templates/rainbows/rainbows.conf.erb +18 -0
- data/templates/tasks/sunshine.rake +114 -0
- data/templates/unicorn/unicorn.conf.erb +6 -0
- data/test/fixtures/app_configs/test_app.yml +11 -0
- data/test/fixtures/sunshine_test/test_upload +0 -0
- data/test/mocks/mock_object.rb +179 -0
- data/test/mocks/mock_open4.rb +117 -0
- data/test/test_helper.rb +188 -0
- data/test/unit/test_app.rb +489 -0
- data/test/unit/test_binder.rb +20 -0
- data/test/unit/test_crontab.rb +128 -0
- data/test/unit/test_git_repo.rb +26 -0
- data/test/unit/test_healthcheck.rb +70 -0
- data/test/unit/test_nginx.rb +107 -0
- data/test/unit/test_rainbows.rb +26 -0
- data/test/unit/test_remote_shell.rb +102 -0
- data/test/unit/test_repo.rb +42 -0
- data/test/unit/test_server.rb +324 -0
- data/test/unit/test_server_app.rb +425 -0
- data/test/unit/test_shell.rb +97 -0
- data/test/unit/test_sunshine.rb +157 -0
- data/test/unit/test_svn_repo.rb +55 -0
- data/test/unit/test_unicorn.rb +22 -0
- metadata +217 -0
@@ -0,0 +1,554 @@
|
|
1
|
+
module Sunshine
|
2
|
+
|
3
|
+
##
|
4
|
+
# Handles App deployment functionality for a single deploy server.
|
5
|
+
#
|
6
|
+
# Server apps can be assigned any number of roles for classification.
|
7
|
+
# :roles:: sym|array - roles assigned (web, db, app, etc...)
|
8
|
+
# By default server apps get the special :all role which will
|
9
|
+
# always return true when calling:
|
10
|
+
# server_app.has_roles? :some_role
|
11
|
+
#
|
12
|
+
# ServerApp objects can be instantiated several ways:
|
13
|
+
# ServerApp.new app_instance, shell_instance, options_hash
|
14
|
+
#
|
15
|
+
# When passing an App instance, the new ServerApp will keep an active link
|
16
|
+
# to the app's properties. Name, deploy, and path attributes will be
|
17
|
+
# actively linked.
|
18
|
+
#
|
19
|
+
# Rely on ServerApp to create a RemoteShell instance to use:
|
20
|
+
# ServerApp.new app_instance, "host.com", options_hash
|
21
|
+
#
|
22
|
+
# Instantiate with app name and rely on Sunshine defaults for app paths:
|
23
|
+
# ServerApp.new "app_name", shell_instance, options_hash
|
24
|
+
#
|
25
|
+
# Explicitely assign the app's root path:
|
26
|
+
# ServerApp.new "app_name", ..., :root_path => "/path/to/app_root"
|
27
|
+
#
|
28
|
+
# Assigning a specific deploy name to use can be done with the
|
29
|
+
# :deploy_name option:
|
30
|
+
# ServerApp.new "app_name", ..., :deploy_name => "deploy"
|
31
|
+
|
32
|
+
class ServerApp
|
33
|
+
|
34
|
+
|
35
|
+
##
|
36
|
+
# Define an attribue that will get a value from app, or locally if
|
37
|
+
# @app isn't set.
|
38
|
+
|
39
|
+
def self.app_attr *attribs
|
40
|
+
attribs.each do |attrib|
|
41
|
+
class_eval <<-STR, __FILE__, __LINE__ + 1
|
42
|
+
def #{attrib}
|
43
|
+
@app ? @app.send(:#{attrib}) : @#{attrib}
|
44
|
+
end
|
45
|
+
STR
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
|
50
|
+
app_attr :name, :deploy_name
|
51
|
+
app_attr :root_path, :checkout_path, :current_path
|
52
|
+
app_attr :deploys_path, :log_path, :shared_path
|
53
|
+
|
54
|
+
attr_accessor :app, :roles, :scripts, :info, :shell, :crontab, :health
|
55
|
+
attr_writer :pkg_manager
|
56
|
+
|
57
|
+
def initialize app, host, options={}
|
58
|
+
|
59
|
+
@app = App === app ? app : nil
|
60
|
+
|
61
|
+
name = @app && @app.name || app
|
62
|
+
assign_local_app_attr name, options
|
63
|
+
|
64
|
+
@deploy_details = nil
|
65
|
+
|
66
|
+
@roles = options[:roles] || [:all]
|
67
|
+
@roles = @roles.split(" ") if String === @roles
|
68
|
+
@roles = [*@roles].compact.map{|r| r.to_sym }
|
69
|
+
|
70
|
+
@scripts = Hash.new{|h, k| h[k] = []}
|
71
|
+
@info = {:ports => {}}
|
72
|
+
|
73
|
+
@pkg_manager = nil
|
74
|
+
|
75
|
+
@shell = case host
|
76
|
+
when String then RemoteShell.new host, options
|
77
|
+
when Shell then host
|
78
|
+
else
|
79
|
+
raise "Could not get remote shell '#{host}'"
|
80
|
+
end
|
81
|
+
|
82
|
+
@crontab = Crontab.new name, @shell
|
83
|
+
@health = Healthcheck.new shared_path, @shell
|
84
|
+
end
|
85
|
+
|
86
|
+
|
87
|
+
##
|
88
|
+
# Add paths the the shell $PATH env.
|
89
|
+
|
90
|
+
def add_shell_paths(*paths)
|
91
|
+
path = shell_env["PATH"] || "$PATH"
|
92
|
+
paths << path
|
93
|
+
|
94
|
+
shell_env.merge! "PATH" => paths.join(":")
|
95
|
+
end
|
96
|
+
|
97
|
+
|
98
|
+
##
|
99
|
+
# Creates and uploads all control scripts for the application.
|
100
|
+
# To add to, or define a control script, see App#add_to_script.
|
101
|
+
|
102
|
+
def build_control_scripts
|
103
|
+
|
104
|
+
write_script "env", make_env_bash_script
|
105
|
+
|
106
|
+
build_scripts = @scripts.dup
|
107
|
+
|
108
|
+
if build_scripts[:restart].empty? &&
|
109
|
+
!build_scripts[:start].empty? && !build_scripts[:stop].empty?
|
110
|
+
build_scripts[:restart] << "#{self.root_path}/stop"
|
111
|
+
build_scripts[:restart] << "#{self.root_path}/start"
|
112
|
+
end
|
113
|
+
|
114
|
+
if build_scripts[:status].empty?
|
115
|
+
build_scripts[:status] << "echo 'No daemons for #{self.name}'; exit 1;"
|
116
|
+
end
|
117
|
+
|
118
|
+
build_scripts.each do |name, cmds|
|
119
|
+
if cmds.empty?
|
120
|
+
Sunshine.logger.warn @shell.host, "#{name} script is empty"
|
121
|
+
end
|
122
|
+
|
123
|
+
bash = make_bash_script name, cmds
|
124
|
+
|
125
|
+
write_script name, bash
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
|
130
|
+
##
|
131
|
+
# Creates a yaml file with deploy information. To add custom information
|
132
|
+
# to the info file, use the app's info hash attribute:
|
133
|
+
# app.info[:key] = "some value"
|
134
|
+
|
135
|
+
def build_deploy_info_file
|
136
|
+
|
137
|
+
deploy_info = get_deploy_info.to_yaml
|
138
|
+
|
139
|
+
@shell.make_file "#{self.checkout_path}/info", deploy_info
|
140
|
+
|
141
|
+
@shell.symlink "#{self.current_path}/info", "#{self.root_path}/info"
|
142
|
+
end
|
143
|
+
|
144
|
+
|
145
|
+
|
146
|
+
##
|
147
|
+
# Checks out the app's codebase to the checkout path.
|
148
|
+
|
149
|
+
def checkout_repo repo
|
150
|
+
@info[:scm] = repo.checkout_to self.checkout_path, @shell
|
151
|
+
end
|
152
|
+
|
153
|
+
|
154
|
+
##
|
155
|
+
# Get post-mortum information about the app's deploy, from the
|
156
|
+
# generated deploy info file.
|
157
|
+
# Post-deploy only.
|
158
|
+
|
159
|
+
def deploy_details reload=false
|
160
|
+
return @deploy_details if @deploy_details && !reload
|
161
|
+
@deploy_details =
|
162
|
+
YAML.load @shell.call("cat #{self.current_path}/info") rescue nil
|
163
|
+
end
|
164
|
+
|
165
|
+
|
166
|
+
##
|
167
|
+
# Checks if the server_app's current info file deploy_name matches
|
168
|
+
# the server_app's deploy_name attribute.
|
169
|
+
|
170
|
+
def deployed?
|
171
|
+
success =
|
172
|
+
@deploy_details[:deploy_name] == self.deploy_name if @deploy_details
|
173
|
+
|
174
|
+
return success if success
|
175
|
+
|
176
|
+
deploy_details(true)[:deploy_name] == self.deploy_name rescue false
|
177
|
+
end
|
178
|
+
|
179
|
+
|
180
|
+
##
|
181
|
+
# An array of all directories used by the app.
|
182
|
+
# Does not include symlinked directories.
|
183
|
+
|
184
|
+
def directories
|
185
|
+
[root_path, deploys_path, shared_path, log_path, checkout_path]
|
186
|
+
end
|
187
|
+
|
188
|
+
|
189
|
+
##
|
190
|
+
# Returns information about the deploy at hand.
|
191
|
+
|
192
|
+
def get_deploy_info
|
193
|
+
{ :deployed_at => Time.now.to_s,
|
194
|
+
:deployed_as => @shell.call("whoami"),
|
195
|
+
:deployed_by => Sunshine.shell.user,
|
196
|
+
:deploy_name => File.basename(self.checkout_path),
|
197
|
+
:roles => @roles,
|
198
|
+
:path => self.root_path
|
199
|
+
}.merge @info
|
200
|
+
end
|
201
|
+
|
202
|
+
|
203
|
+
##
|
204
|
+
# Decrypt a file using gpg. Allows options:
|
205
|
+
# :output:: str - the path the output file should go to
|
206
|
+
# :passphrase:: str - the passphrase gpg should use
|
207
|
+
|
208
|
+
def gpg_decrypt gpg_file, options={}
|
209
|
+
output_file = options[:output] || gpg_file.gsub(/\.gpg$/, '')
|
210
|
+
|
211
|
+
passphrase = options[:passphrase]
|
212
|
+
passphrase_file = "#{self.root_path}/tmp/gpg_passphrase"
|
213
|
+
|
214
|
+
gpg_cmd = "gpg --batch --no-tty --yes --output #{output_file} "+
|
215
|
+
"--passphrase-file #{passphrase_file} --decrypt #{gpg_file}"
|
216
|
+
|
217
|
+
@shell.call "mkdir -p #{File.dirname(passphrase_file)}"
|
218
|
+
|
219
|
+
@shell.make_file passphrase_file, passphrase
|
220
|
+
|
221
|
+
@shell.call "cd #{self.checkout_path} && #{gpg_cmd}"
|
222
|
+
@shell.call "rm -f #{passphrase_file}"
|
223
|
+
end
|
224
|
+
|
225
|
+
|
226
|
+
##
|
227
|
+
# Check if this server app includes the specified roles:
|
228
|
+
|
229
|
+
def has_roles? *roles
|
230
|
+
return true if @roles.include? :all
|
231
|
+
|
232
|
+
roles.each do |role|
|
233
|
+
return false unless @roles.include? role
|
234
|
+
end
|
235
|
+
|
236
|
+
true
|
237
|
+
end
|
238
|
+
|
239
|
+
|
240
|
+
%w{gem yum apt}.each do |dep_type|
|
241
|
+
self.class_eval <<-STR, __FILE__, __LINE__ + 1
|
242
|
+
##
|
243
|
+
# Install one or more #{dep_type} packages.
|
244
|
+
# See #{dep_type.capitalize}#new for supported options.
|
245
|
+
|
246
|
+
def #{dep_type}_install(*names)
|
247
|
+
options = Hash === names.last ? names.delete_at(-1) : Hash.new
|
248
|
+
|
249
|
+
names.each do |name|
|
250
|
+
dep = #{dep_type.capitalize}.new(name, options)
|
251
|
+
dep.install! :call => @shell
|
252
|
+
end
|
253
|
+
end
|
254
|
+
STR
|
255
|
+
end
|
256
|
+
|
257
|
+
|
258
|
+
##
|
259
|
+
# Install dependencies previously defined in Sunshine.dependencies.
|
260
|
+
|
261
|
+
def install_deps(*deps)
|
262
|
+
options = {:call => @shell, :prefer => pkg_manager}
|
263
|
+
options.merge! deps.delete_at(-1) if Hash === deps.last
|
264
|
+
|
265
|
+
args = deps << options
|
266
|
+
Sunshine.dependencies.install(*args)
|
267
|
+
end
|
268
|
+
|
269
|
+
|
270
|
+
##
|
271
|
+
# Creates the required application directories.
|
272
|
+
|
273
|
+
def make_app_directories
|
274
|
+
@shell.call "mkdir -p #{self.directories.join(" ")}"
|
275
|
+
end
|
276
|
+
|
277
|
+
|
278
|
+
##
|
279
|
+
# Makes an array of bash commands into a script that
|
280
|
+
# echoes 'true' on success.
|
281
|
+
|
282
|
+
def make_bash_script name, cmds
|
283
|
+
cmds = cmds.map{|cmd| "(#{cmd})" }
|
284
|
+
|
285
|
+
cmds << "echo true"
|
286
|
+
|
287
|
+
bash = <<-STR
|
288
|
+
#!/bin/bash
|
289
|
+
if [ "$1" == "--no-env" ]; then
|
290
|
+
#{cmds.flatten.join(" && ")}
|
291
|
+
else
|
292
|
+
#{self.root_path}/env #{self.root_path}/#{name} --no-env
|
293
|
+
fi
|
294
|
+
STR
|
295
|
+
end
|
296
|
+
|
297
|
+
|
298
|
+
##
|
299
|
+
# Creates the one-off env script that will be used by other scripts
|
300
|
+
# to correctly set their env variables.
|
301
|
+
|
302
|
+
def make_env_bash_script
|
303
|
+
env_str = shell_env.map{|e| e.join("=")}.join(" ")
|
304
|
+
"#!/bin/bash\nenv #{env_str} \"$@\""
|
305
|
+
end
|
306
|
+
|
307
|
+
|
308
|
+
##
|
309
|
+
# Returns the type of package management system to use.
|
310
|
+
|
311
|
+
def pkg_manager
|
312
|
+
@pkg_manager ||=
|
313
|
+
(@shell.call("yum --version") && Yum) rescue Apt
|
314
|
+
end
|
315
|
+
|
316
|
+
|
317
|
+
##
|
318
|
+
# Run a rake task the deploy server.
|
319
|
+
|
320
|
+
def rake command
|
321
|
+
install_deps 'rake', :type => Gem
|
322
|
+
@shell.call "cd #{self.checkout_path} && rake #{command}"
|
323
|
+
end
|
324
|
+
|
325
|
+
|
326
|
+
##
|
327
|
+
# Adds the app to the deploy server's deployed-apps list
|
328
|
+
|
329
|
+
def register_as_deployed
|
330
|
+
AddCommand.exec self.root_path, 'servers' => [@shell]
|
331
|
+
end
|
332
|
+
|
333
|
+
|
334
|
+
##
|
335
|
+
# Removes old deploys from the checkout_dir
|
336
|
+
# based on Sunshine's max_deploy_versions.
|
337
|
+
|
338
|
+
def remove_old_deploys
|
339
|
+
deploys = @shell.call("ls -1 #{self.deploys_path}").split("\n")
|
340
|
+
|
341
|
+
return unless deploys.length > Sunshine.max_deploy_versions
|
342
|
+
|
343
|
+
lim = Sunshine.max_deploy_versions + 1
|
344
|
+
|
345
|
+
rm_deploys = deploys[0..-lim]
|
346
|
+
rm_deploys.map!{|d| "#{self.deploys_path}/#{d}"}
|
347
|
+
|
348
|
+
@shell.call("rm -rf #{rm_deploys.join(" ")}")
|
349
|
+
end
|
350
|
+
|
351
|
+
|
352
|
+
##
|
353
|
+
# Run the app's restart script. Returns false on failure.
|
354
|
+
# Post-deploy only.
|
355
|
+
|
356
|
+
def restart
|
357
|
+
@shell.call "#{self.root_path}/restart" rescue false
|
358
|
+
end
|
359
|
+
|
360
|
+
|
361
|
+
##
|
362
|
+
# Symlink current directory to previous checkout and remove
|
363
|
+
# the current deploy directory.
|
364
|
+
|
365
|
+
def revert!
|
366
|
+
@shell.call "rm -rf #{self.checkout_path}"
|
367
|
+
|
368
|
+
last_deploy = @shell.call("ls -rc1 #{self.deploys_path}").split("\n").last
|
369
|
+
|
370
|
+
if last_deploy && !last_deploy.empty?
|
371
|
+
@shell.symlink "#{self.deploys_path}/#{last_deploy}", self.current_path
|
372
|
+
|
373
|
+
Sunshine.logger.info @shell.host, "Reverted to #{last_deploy}"
|
374
|
+
|
375
|
+
unless start :force => true
|
376
|
+
Sunshine.logger.error @shell.host, "Failed #{@name} startup"
|
377
|
+
end
|
378
|
+
|
379
|
+
else
|
380
|
+
@crontab.delete!
|
381
|
+
|
382
|
+
Sunshine.logger.info @shell.host, "No previous deploy to revert to."
|
383
|
+
end
|
384
|
+
end
|
385
|
+
|
386
|
+
|
387
|
+
##
|
388
|
+
# Runs bundler. Installs the bundler gem if missing.
|
389
|
+
|
390
|
+
def run_bundler
|
391
|
+
install_deps 'bundler', :type => Gem
|
392
|
+
@shell.call "cd #{self.checkout_path} && gem bundle"
|
393
|
+
end
|
394
|
+
|
395
|
+
|
396
|
+
##
|
397
|
+
# Runs geminstaller. :(
|
398
|
+
# Deprecated: use bundler
|
399
|
+
|
400
|
+
def run_geminstaller
|
401
|
+
install_deps 'geminstaller', :type => Gem
|
402
|
+
@shell.call "cd #{self.checkout_path} && geminstaller -e"
|
403
|
+
end
|
404
|
+
|
405
|
+
|
406
|
+
##
|
407
|
+
# Check if the app pids are present.
|
408
|
+
# Post-deploy only.
|
409
|
+
|
410
|
+
def running?
|
411
|
+
@shell.call "#{self.root_path}/status" rescue false
|
412
|
+
end
|
413
|
+
|
414
|
+
|
415
|
+
##
|
416
|
+
# Run a sass task on any or all deploy servers.
|
417
|
+
|
418
|
+
def sass *sass_names
|
419
|
+
install_deps 'haml', :type => Gem
|
420
|
+
|
421
|
+
sass_names.flatten.each do |name|
|
422
|
+
sass_file = "public/stylesheets/sass/#{name}.sass"
|
423
|
+
css_file = "public/stylesheets/#{name}.css"
|
424
|
+
sass_cmd = "cd #{self.checkout_path} && sass #{sass_file} #{css_file}"
|
425
|
+
|
426
|
+
@shell.call sass_cmd
|
427
|
+
end
|
428
|
+
end
|
429
|
+
|
430
|
+
|
431
|
+
##
|
432
|
+
# Get the deploy server's shell environment.
|
433
|
+
|
434
|
+
def shell_env
|
435
|
+
@shell.env
|
436
|
+
end
|
437
|
+
|
438
|
+
|
439
|
+
##
|
440
|
+
# Run the app's start script. Returns false on failure.
|
441
|
+
# Post-deploy only.
|
442
|
+
|
443
|
+
def start options=nil
|
444
|
+
options ||= {}
|
445
|
+
|
446
|
+
if running?
|
447
|
+
return unless options[:force]
|
448
|
+
stop
|
449
|
+
end
|
450
|
+
|
451
|
+
@shell.call "#{self.root_path}/start" rescue false
|
452
|
+
end
|
453
|
+
|
454
|
+
|
455
|
+
##
|
456
|
+
# Get the app's status: :running or :down.
|
457
|
+
|
458
|
+
def status
|
459
|
+
running? ? :running : :down
|
460
|
+
end
|
461
|
+
|
462
|
+
|
463
|
+
##
|
464
|
+
# Run the app's stop script. Returns false on failure.
|
465
|
+
# Post-deploy only.
|
466
|
+
|
467
|
+
def stop
|
468
|
+
@shell.call "#{self.root_path}/stop" rescue false
|
469
|
+
end
|
470
|
+
|
471
|
+
|
472
|
+
##
|
473
|
+
# Creates a symlink to the app's checkout path.
|
474
|
+
|
475
|
+
def symlink_current_dir
|
476
|
+
@shell.symlink self.checkout_path, self.current_path
|
477
|
+
end
|
478
|
+
|
479
|
+
|
480
|
+
##
|
481
|
+
# Upload common rake tasks from a local path or the sunshine lib.
|
482
|
+
# app.upload_tasks
|
483
|
+
# #=> upload all tasks
|
484
|
+
# app.upload_tasks 'app', 'common', ...
|
485
|
+
# #=> upload app and common rake files
|
486
|
+
#
|
487
|
+
# File paths may also be used instead of the file's base name but
|
488
|
+
# directory structures will not be followed:
|
489
|
+
# app.upload_tasks 'lib/common/app.rake', 'lib/do_thing.rake'
|
490
|
+
#
|
491
|
+
# Allows options:
|
492
|
+
# :local_path:: str - the path to get rake tasks from
|
493
|
+
# :remote_path:: str - the remote absolute path to upload the files to
|
494
|
+
|
495
|
+
def upload_tasks *files
|
496
|
+
options = Hash === files[-1] ? files.delete_at(-1) : {}
|
497
|
+
remote_path = options[:remote_path] || "#{self.checkout_path}/lib/tasks"
|
498
|
+
local_path = options[:local_path] || "#{Sunshine::ROOT}/templates/tasks"
|
499
|
+
|
500
|
+
@shell.call "mkdir -p #{remote_path}"
|
501
|
+
|
502
|
+
files.map! do |file|
|
503
|
+
if File.basename(file) == file
|
504
|
+
File.join(local_path, "#{file}.rake")
|
505
|
+
else
|
506
|
+
file
|
507
|
+
end
|
508
|
+
end
|
509
|
+
|
510
|
+
files = Dir.glob("#{Sunshine::ROOT}/templates/tasks/*") if files.empty?
|
511
|
+
|
512
|
+
files.each do |file|
|
513
|
+
remote_file = File.join remote_path, File.basename(file)
|
514
|
+
@shell.upload file, remote_file
|
515
|
+
end
|
516
|
+
end
|
517
|
+
|
518
|
+
|
519
|
+
##
|
520
|
+
# Write an executable bash script to the app's checkout dir
|
521
|
+
# on the deploy server, and symlink them to the current dir.
|
522
|
+
|
523
|
+
def write_script name, contents
|
524
|
+
|
525
|
+
@shell.make_file "#{self.checkout_path}/#{name}", contents,
|
526
|
+
:flags => '--chmod=ugo=rwx'
|
527
|
+
|
528
|
+
@shell.symlink "#{self.current_path}/#{name}",
|
529
|
+
"#{self.root_path}/#{name}"
|
530
|
+
end
|
531
|
+
|
532
|
+
|
533
|
+
private
|
534
|
+
|
535
|
+
|
536
|
+
##
|
537
|
+
# Set all the app paths based on the root app path.
|
538
|
+
|
539
|
+
def assign_local_app_attr name, options={}
|
540
|
+
@name = name
|
541
|
+
@deploy_name = options[:deploy_name] || Time.now.to_i
|
542
|
+
|
543
|
+
default_root = File.join(Sunshine.web_directory, @name)
|
544
|
+
@root_path = options[:root_path] || default_root
|
545
|
+
|
546
|
+
@current_path = "#{@root_path}/current"
|
547
|
+
@deploys_path = "#{@root_path}/deploys"
|
548
|
+
@shared_path = "#{@root_path}/shared"
|
549
|
+
@log_path = "#{@shared_path}/log"
|
550
|
+
@checkout_path = "#{@deploys_path}/#{@deploy_name}"
|
551
|
+
end
|
552
|
+
end
|
553
|
+
end
|
554
|
+
|